From c529e98753a9a3776f7aa919b11d67d82be46318 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Fri, 16 May 2025 18:25:05 +0700 Subject: [PATCH 01/10] fix: treat URL input same as QR imput --- .../UI/Payments/PaymentModels/DWPaymentProcessor.m | 2 +- Podfile.lock | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/DashWallet/Sources/UI/Payments/PaymentModels/DWPaymentProcessor.m b/DashWallet/Sources/UI/Payments/PaymentModels/DWPaymentProcessor.m index a9e883052..e9ce68724 100644 --- a/DashWallet/Sources/UI/Payments/PaymentModels/DWPaymentProcessor.m +++ b/DashWallet/Sources/UI/Payments/PaymentModels/DWPaymentProcessor.m @@ -159,7 +159,7 @@ - (void)processPaymentInput:(DWPaymentInput *)paymentInput { self.paymentInput = paymentInput; if (paymentInput.request) { - if (paymentInput.source == DWPaymentInputSource_ScanQR && paymentInput.request.isValidAsNonDashpayPaymentRequest) { + if ((paymentInput.source == DWPaymentInputSource_ScanQR || paymentInput.source == DWPaymentInputSource_URL) && paymentInput.request.isValidAsNonDashpayPaymentRequest) { DSPaymentProtocolRequest *protocolRequest = [self protocolRequestFromPaymentRequest:self.paymentInput.request]; [self txManagerRequestingAdditionalInfo:DSRequestingAdditionalInfo_Amount protocolRequest:protocolRequest]; diff --git a/Podfile.lock b/Podfile.lock index b6fc51f11..919d15a97 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -591,10 +591,11 @@ PODS: - "!ProtoCompiler-gRPCPlugin (~> 1.0)" - DAPI-GRPC/Messages - gRPC-ProtoRPC - - DashSharedCore (0.5.0) + - DashSharedCore (0.5.1) - DashSync (0.1.0): - CocoaLumberjack (= 3.7.2) - DAPI-GRPC (= 0.22.0-dev.8) + - DashSharedCore (= 0.5.1) - DSDynamicOptions (= 0.1.2) - DWAlertController (= 0.2.1) - TinyCborObjc (= 0.4.6) @@ -736,7 +737,6 @@ PODS: DEPENDENCIES: - CloudInAppMessaging (= 0.1.0) - CocoaImageHashing (from `https://github.com/ameingast/cocoaimagehashing.git`, commit `ad01eee`) - - DashSharedCore (from `../dash-shared-core/`) - DashSync (from `../DashSync/`) - DSDynamicOptions (= 0.1.2) - Firebase/DynamicLinks @@ -766,6 +766,7 @@ SPEC REPOS: - CloudInAppMessaging - CocoaLumberjack - DAPI-GRPC + - DashSharedCore - DSDynamicOptions - DWAlertController - Firebase @@ -803,8 +804,6 @@ EXTERNAL SOURCES: CocoaImageHashing: :commit: ad01eee :git: https://github.com/ameingast/cocoaimagehashing.git - DashSharedCore: - :path: "../dash-shared-core/" DashSync: :path: "../DashSync/" MMSegmentSlider: @@ -832,8 +831,8 @@ SPEC CHECKSUMS: CocoaImageHashing: 8656031d0899abe6c1c415827de43e9798189c53 CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da DAPI-GRPC: 138d62523bbfe7e88a39896f1053c0bc12390d9f - DashSharedCore: 18baa0f6c2bc2b4fc4628651d293f4fd6645025f - DashSync: 2438dbf626f13a8633ccc19c718c1c223c8ee831 + DashSharedCore: b8481feb5f08acf162b548edbfc7a9b1ce491141 + DashSync: 1f5741aad267dcc0cfc04b6903490d304232ddf2 DSDynamicOptions: 347cc5d2c4e080eb3de6a86719ad3d861b82adfc DWAlertController: 5f4cd8adf90336331c054857f709f5f8d4b16a5b Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d @@ -868,6 +867,6 @@ SPEC CHECKSUMS: TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 UIViewController-KeyboardAdditions: a691dc7e63a49854d341455a778ee8497dfc4662 -PODFILE CHECKSUM: 1ec71e13430fe0345b364b97448746daa931e0b4 +PODFILE CHECKSUM: a5ef71862394897c78a0cc247502754372e88c07 COCOAPODS: 1.15.2 From d7236bdab5be2b25ce2aeb5f762f8b13ce39691a Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Fri, 16 May 2025 18:46:25 +0700 Subject: [PATCH 02/10] fix: auth for show balance button --- .../ProvideAmountViewController.swift | 1 + .../Sources/UI/SwiftUI Components/SendIntro.swift | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift b/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift index 9c066dc55..25e169044 100644 --- a/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift +++ b/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift @@ -193,6 +193,7 @@ struct ProvideAmountIntro: View { destination: destination, dashBalance: CoinJoinService.shared.mixingState.isInProgress ? model.coinJoinBalance : model.walletBalance, balanceLabel: balanceLabel + ":", + authCallback: model.auth, avatarView: avatarView ) } diff --git a/DashWallet/Sources/UI/SwiftUI Components/SendIntro.swift b/DashWallet/Sources/UI/SwiftUI Components/SendIntro.swift index 3af1ad2d2..d1f6cd43f 100644 --- a/DashWallet/Sources/UI/SwiftUI Components/SendIntro.swift +++ b/DashWallet/Sources/UI/SwiftUI Components/SendIntro.swift @@ -24,6 +24,7 @@ struct SendIntro: View { var destination: String? = nil var dashBalance: UInt64? = nil var balanceLabel: String? = nil + var authCallback: ((@escaping (Bool) -> Void) -> Void)? = nil @ViewBuilder var avatarView: () -> Content var body: some View { @@ -63,7 +64,7 @@ struct SendIntro: View { } Button(action: { - balanceHidden.toggle() + toggleBalanceVisibility() }) { Image(systemName: balanceHidden ? "eye.slash.fill" : "eye.fill") .resizable() @@ -82,6 +83,18 @@ struct SendIntro: View { }.frame(maxWidth: .infinity, alignment: .leading) } + private func toggleBalanceVisibility() { + if let authCallback = authCallback, balanceHidden { + authCallback { [self] isAuthenticated in + if isAuthenticated { + balanceHidden.toggle() + } + } + } else { + balanceHidden.toggle() + } + } + @ViewBuilder private func FormattedFiatText(from dashAmount: UInt64) -> some View { let text = (try? CurrencyExchanger.shared.convertDash(amount: dashAmount.dashAmount, to: App.fiatCurrency).formattedFiatAmount) ?? NSLocalizedString("Not available", comment: "") From c3b42b48a4f30c7df8903516da1258f8f3a8004d Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Wed, 21 May 2025 17:34:40 +0800 Subject: [PATCH 03/10] feat: ctx model draft --- .../Explore Dash/Model/CTXSpendModels.swift | 68 +++++++++++++ .../Explore Dash/Services/CTXSpendAPI.swift | 26 ++++- .../Services/CTXSpendService.swift | 71 +++++++++++++- .../Models/Uphold/DWUpholdMainnetConstants.m | 1 - .../Views/DashSpend/DashSpendPayScreen.swift | 96 +++++++++++++++++-- .../DashSpend/DashSpendPayViewModel.swift | 78 +++++++++++++++ DashWallet/ar.lproj/Localizable.strings | 39 +++++++- DashWallet/bg.lproj/Localizable.strings | 39 +++++++- DashWallet/ca.lproj/Localizable.strings | 39 +++++++- DashWallet/cs.lproj/Localizable.strings | 39 +++++++- DashWallet/da.lproj/Localizable.strings | 39 +++++++- DashWallet/de.lproj/Localizable.strings | 39 +++++++- DashWallet/el.lproj/Localizable.strings | 39 +++++++- DashWallet/en.lproj/Localizable.strings | 39 +++++++- DashWallet/eo.lproj/Localizable.strings | 39 +++++++- DashWallet/es.lproj/Localizable.strings | 39 +++++++- DashWallet/et.lproj/Localizable.strings | 39 +++++++- DashWallet/fa.lproj/Localizable.strings | 39 +++++++- DashWallet/fi.lproj/Localizable.strings | 39 +++++++- DashWallet/fil.lproj/Localizable.strings | 39 +++++++- DashWallet/fr.lproj/Localizable.strings | 39 +++++++- DashWallet/hr.lproj/Localizable.strings | 39 +++++++- DashWallet/hu.lproj/Localizable.strings | 39 +++++++- DashWallet/id.lproj/Localizable.strings | 39 +++++++- DashWallet/it.lproj/Localizable.strings | 39 +++++++- DashWallet/ja.lproj/Localizable.strings | 39 +++++++- DashWallet/ko.lproj/Localizable.strings | 39 +++++++- DashWallet/mk.lproj/Localizable.strings | 39 +++++++- DashWallet/ms.lproj/Localizable.strings | 39 +++++++- DashWallet/nb.lproj/Localizable.strings | 39 +++++++- DashWallet/nl.lproj/Localizable.strings | 39 +++++++- DashWallet/pl.lproj/Localizable.strings | 39 +++++++- DashWallet/pt.lproj/Localizable.strings | 39 +++++++- DashWallet/ro.lproj/Localizable.strings | 39 +++++++- DashWallet/ru.lproj/Localizable.strings | 39 +++++++- DashWallet/sk.lproj/Localizable.strings | 39 +++++++- DashWallet/sl.lproj/Localizable.strings | 39 +++++++- DashWallet/sl_SI.lproj/Localizable.strings | 39 +++++++- DashWallet/sq.lproj/Localizable.strings | 39 +++++++- DashWallet/sr.lproj/Localizable.strings | 39 +++++++- DashWallet/sv.lproj/Localizable.strings | 39 +++++++- DashWallet/th.lproj/Localizable.strings | 39 +++++++- DashWallet/tr.lproj/Localizable.strings | 39 +++++++- DashWallet/uk.lproj/Localizable.strings | 39 +++++++- DashWallet/vi.lproj/Localizable.strings | 39 +++++++- DashWallet/zh-Hans.lproj/Localizable.strings | 39 +++++++- .../zh-Hant-TW.lproj/Localizable.strings | 39 +++++++- DashWallet/zh.lproj/Localizable.strings | 39 +++++++- DashWallet/zh_TW.lproj/Localizable.strings | 39 +++++++- 49 files changed, 1874 insertions(+), 143 deletions(-) create mode 100644 DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift diff --git a/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift new file mode 100644 index 000000000..faef2576e --- /dev/null +++ b/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift @@ -0,0 +1,68 @@ +import Foundation + +// MARK: - Request Models + +struct LoginRequest: Codable { + let email: String +} + +struct VerifyEmailRequest: Codable { + let email: String + let code: String +} + +struct PurchaseGiftCardRequest: Codable { + let cryptoCurrency: String + let fiatCurrency: String + let fiatAmount: String + let merchantId: String +} + +// MARK: - Response Models + +struct VerifyEmailResponse: Codable { + let accessToken: String + let refreshToken: String +} + +struct GiftCardResponse: Codable { + let cryptoCurrency: String + let fiatCurrency: String + let fiatAmount: String + let merchantName: String + let merchantId: String + let iconUrl: String? + let barcode: String? + let barcodeType: String? + let dashPaymentUrl: String + let dashAmount: String + let claimCode: String? + let status: String + let txid: String? + let createdAt: String +} + +struct MerchantResponse: Codable { + let id: String + let name: String + let website: String + let logoUrl: String + let enabled: Bool + let minimumCardPurchase: Double + let maximumCardPurchase: Double + let savingsPercentage: Double + let denominationType: DenominationType + let denominations: [Double] + + enum CodingKeys: String, CodingKey { + case id, name, website, enabled + case logoUrl = "logoLocation" + case minimumCardPurchase, maximumCardPurchase + case savingsPercentage, denominationType, denominations + } +} + +enum DenominationType: String, Codable { + case Range = "range" + case Fixed = "fixed" +} \ No newline at end of file diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift index 7f382e568..fa5b6f9e0 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift @@ -18,12 +18,36 @@ import Foundation import Moya -enum CTXSpendError: Error { +enum CTXSpendError: Error, LocalizedError { case networkError case parsingError case invalidCode case unauthorized + case insufficientFunds + case invalidMerchant + case invalidAmount case unknown + + public var errorDescription: String? { + switch self { + case .networkError: + return NSLocalizedString("Network error. Please check your connection and try again.", comment: "CTXSpend error") + case .parsingError: + return NSLocalizedString("Error processing server response. Please try again later.", comment: "CTXSpend error") + case .invalidCode: + return NSLocalizedString("Invalid verification code. Please try again.", comment: "CTXSpend error") + case .unauthorized: + return NSLocalizedString("Please sign in to your DashSpend account.", comment: "CTXSpend error") + case .insufficientFunds: + return NSLocalizedString("Insufficient funds to complete this purchase.", comment: "CTXSpend error") + case .invalidMerchant: + return NSLocalizedString("This merchant is currently unavailable.", comment: "CTXSpend error") + case .invalidAmount: + return NSLocalizedString("Invalid amount. Please check merchant limits.", comment: "CTXSpend error") + case .unknown: + return NSLocalizedString("An unknown error occurred. Please try again later.", comment: "CTXSpend error") + } + } } protocol CTXSpendAPIAccessTokenProvider: AnyObject { diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift index 977e6e116..1ba78963e 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift @@ -102,17 +102,80 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { ) do { - return try await CTXSpendAPI.shared.request(.purchaseGiftCard(request)) + let response = try await CTXSpendAPI.shared.request(.purchaseGiftCard(request)) + DSLogger.log("Gift card purchased successfully: \(response)") + return response + } catch let error as CTXSpendError { + DSLogger.log("Gift card purchase failed with CTXSpendError: \(error)") + throw error + } catch let error as HTTPClientError { + DSLogger.log("Gift card purchase failed with HTTPClientError: \(error)") + + if case .statusCode(let response) = error { + switch response.statusCode { + case 400: + if let errorData = try? JSONDecoder().decode(CTXSpendAPIError.self, from: response.data), + let firstError = errorData.errors.first { + // Look for specific error messages + let errorMessage = firstError.message.lowercased() + + if errorMessage.contains("insufficient") || errorMessage.contains("funds") { + throw CTXSpendError.insufficientFunds + } else if errorMessage.contains("merchant") { + throw CTXSpendError.invalidMerchant + } else if errorMessage.contains("amount") || errorMessage.contains("value") { + throw CTXSpendError.invalidAmount + } + + // Custom error with the actual message from API + throw NSError(domain: "CTXSpend", code: 400, userInfo: [NSLocalizedDescriptionKey: firstError.message]) + } + case 401, 403: + throw CTXSpendError.unauthorized + case 404: + throw CTXSpendError.invalidMerchant + case 500...599: + throw CTXSpendError.networkError + default: + break + } + } + + throw CTXSpendError.unknown } catch { - throw mapError(error) + DSLogger.log("Gift card purchase failed with error: \(error)") + throw CTXSpendError.networkError } } func getMerchant(merchantId: String) async throws -> MerchantResponse { do { - return try await CTXSpendAPI.shared.request(.getMerchant(merchantId)) + let response = try await CTXSpendAPI.shared.request(.getMerchant(merchantId)) + DSLogger.log("Successfully retrieved merchant info: \(merchantId)") + return response + } catch let error as CTXSpendError { + DSLogger.log("Failed to get merchant with CTXSpendError: \(error)") + throw error + } catch let error as HTTPClientError { + DSLogger.log("Failed to get merchant with HTTPClientError: \(error)") + + if case .statusCode(let response) = error { + switch response.statusCode { + case 401, 403: + throw CTXSpendError.unauthorized + case 404: + throw CTXSpendError.invalidMerchant + case 500...599: + throw CTXSpendError.networkError + default: + break + } + } + + throw CTXSpendError.unknown } catch { - throw mapError(error) + DSLogger.log("Failed to get merchant with error: \(error)") + throw CTXSpendError.networkError } } diff --git a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m index 15830fe78..a7f171e16 100644 --- a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m +++ b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m @@ -47,7 +47,6 @@ + (NSString *)transactionURLFormat { + (NSString *)logoutURLString { return @"https://uphold.com/"; - } @end diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 24720fcde..955fe54c4 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -24,8 +24,11 @@ struct DashSpendPayScreen: View { @StateObject private var viewModel: DashSpendPayViewModel let merchant: ExplorePointOfUse @State var justAuthenticated: Bool - @State var showConfirmToast: Bool // TODO: temp + @State var showConfirmToast: Bool @State private var showConfirmationDialog = false + @State private var showErrorDialog = false + @State private var errorMessage = "" + @State private var errorTitle = "" init(merchant: ExplorePointOfUse, justAuthenticated: Bool = false) { self.merchant = merchant @@ -120,8 +123,13 @@ struct DashSpendPayScreen: View { value: $viewModel.input, showDecimalSeparator: true, actionButtonText: NSLocalizedString("Preview", comment: ""), - actionEnabled: viewModel.error == nil && !viewModel.showLimits, + actionEnabled: viewModel.error == nil && !viewModel.showLimits && !viewModel.isLoading, actionHandler: { + if !viewModel.isUserSignedIn() { + showSignInError() + return + } + showConfirmationDialog = true } ) @@ -144,11 +152,27 @@ struct DashSpendPayScreen: View { if showConfirmToast { ToastView( - text: NSLocalizedString("Not implemented", comment: "") + text: NSLocalizedString("Gift card purchase successful", comment: "DashSpend") ) .frame(height: 20) .padding(.bottom, 30) } + + if showErrorDialog { + ModalDialog( + style: .error, + icon: .system("exclamationmark.triangle.fill"), + heading: errorTitle, + textBlock1: errorMessage, + positiveButtonText: NSLocalizedString("OK", comment: ""), + positiveButtonAction: { + showErrorDialog = false + } + ) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.black.opacity(0.7)) + .edgesIgnoringSafeArea(.all) + } } .ignoresSafeArea(.all, edges: .bottom) .background(Color.primaryBackground) @@ -176,12 +200,8 @@ struct DashSpendPayScreen: View { originalPrice: viewModel.amount, discount: viewModel.savingsFraction, onConfirm: { - // TODO: Handle confirmation action showConfirmationDialog = false - showConfirmToast = true - DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - showConfirmToast = false - } + purchaseGiftCard() }, onCancel: { showConfirmationDialog = false @@ -196,6 +216,66 @@ struct DashSpendPayScreen: View { } } } + + private func purchaseGiftCard() { + Task { + do { + // Show spinner/activity indicator could be added here + + let response = try await viewModel.purchaseGiftCard() + + // Success! Show success message and log to console + print("============ GIFT CARD PURCHASE SUCCESSFUL ============") + print("Merchant: \(response.merchantName)") + print("Amount: \(response.fiatCurrency) \(response.fiatAmount)") + print("Dash Amount: \(response.dashAmount)") + print("Dash Payment URL: \(response.dashPaymentUrl)") + + if let claimCode = response.claimCode { + print("Claim Code: \(claimCode)") + } + + if let barcode = response.barcode { + print("Barcode: \(barcode)") + if let barcodeType = response.barcodeType { + print("Barcode Type: \(barcodeType)") + } + } + + if let txid = response.txid { + print("Transaction ID: \(txid)") + } + + print("Created At: \(response.createdAt)") + print("Status: \(response.status)") + print("====================================================") + + showConfirmToast = true + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + showConfirmToast = false + // In a real implementation, we would navigate to a gift card details screen + } + } catch let error as CTXSpendError { + errorTitle = NSLocalizedString("Purchase Failed", comment: "Alert title") + errorMessage = error.localizedDescription + showErrorDialog = true + + print("Gift card purchase failed with CTXSpendError: \(error)") + } catch { + errorTitle = NSLocalizedString("Error", comment: "Alert title") + errorMessage = error.localizedDescription + showErrorDialog = true + + print("Gift card purchase failed with error: \(error)") + } + } + } + + private func showSignInError() { + errorTitle = NSLocalizedString("Sign in required", comment: "Alert title") + errorMessage = NSLocalizedString("You need to sign in to DashSpend to purchase gift cards.", comment: "DashSpend") + showErrorDialog = true + } } struct ConfirmationDialog: View { diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 588b98463..4ea69c1d6 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -24,11 +24,13 @@ private let defaultCurrency = kDefaultCurrencyCode class DashSpendPayViewModel: ObservableObject { private var cancellableBag = Set() private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: defaultCurrency) + private let ctxSpendService = CTXSpendService.shared private let minimumAmount: Decimal = 5 // TODO: limits private let maximumAmount: Decimal = 50 private(set) var amount: Decimal = 0 private(set) var savingsFraction: Decimal = 0.0 + @Published private(set) var isLoading = false let currencySymbol: String = { let locale = Locale.current as NSLocale @@ -64,6 +66,8 @@ class DashSpendPayViewModel: ObservableObject { } } + private var merchantId: String = "" + var costMessage: String { let originalPrice = fiatFormatter.string(for: amount) ?? "0.00" let discountedPrice = amount * (1 - savingsFraction) @@ -84,6 +88,10 @@ class DashSpendPayViewModel: ObservableObject { merchantTitle = merchant.name merchantIconUrl = merchant.logoLocation ?? "" savingsFraction = Decimal(merchant.merchant?.savingsBasisPoints ?? 0) / Decimal(10000) + + if let merchantId = merchant.merchant?.merchantId { + self.merchantId = merchantId + } } func subscribeToUpdates() { @@ -101,6 +109,11 @@ class DashSpendPayViewModel: ObservableObject { } self.refreshBalance() + + // Get updated merchant info from CTX API if user is signed in + Task { + await updateMerchantInfo() + } } func unsubscribeFromAll() { @@ -135,4 +148,69 @@ class DashSpendPayViewModel: ObservableObject { return dashAmount.plainDashAmount > allAvailableFunds } + + // MARK: - CTX Integration + + private func updateMerchantInfo() async { + guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { return } + + do { + let merchantInfo = try await ctxSpendService.getMerchant(merchantId: merchantId) + + // Update merchant details + savingsFraction = Decimal(merchantInfo.savingsPercentage) / 100 + + if merchantInfo.denominationType == .Range { + minimumAmount = Decimal(merchantInfo.minimumCardPurchase) + maximumAmount = Decimal(merchantInfo.maximumCardPurchase) + } + + // Revalidate current amount + checkAmountForErrors() + } catch { + DSLogger.log("Failed to get merchant info: \(error)") + } + } + + func purchaseGiftCard() async throws -> GiftCardResponse { + guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { + DSLogger.log("Purchase gift card failed: User not signed in or merchant ID is empty") + throw CTXSpendError.unauthorized + } + + DSLogger.log("Attempting to purchase gift card for merchant \(merchantId) with amount \(amount)") + isLoading = true + defer { isLoading = false } + + do { + let fiatAmountString = String(format: "%.2f", amount) + DSLogger.log("Making API request to purchase gift card: merchantId=\(merchantId), amount=\(fiatAmountString)USD") + + let response = try await ctxSpendService.purchaseGiftCard( + merchantId: merchantId, + fiatAmount: fiatAmountString, + fiatCurrency: "USD", + cryptoCurrency: "DASH" + ) + + // Log success details + DSLogger.log("Gift card purchase successful!") + DSLogger.log("Response details: Merchant=\(response.merchantName), Amount=\(response.fiatAmount) \(response.fiatCurrency)") + DSLogger.log("DASH Amount: \(response.dashAmount)") + DSLogger.log("DASH Payment URL: \(response.dashPaymentUrl)") + + if let txid = response.txid { + DSLogger.log("Transaction ID: \(txid)") + } + + return response + } catch { + DSLogger.log("Gift card purchase failed with error: \(error)") + throw error + } + } + + func isUserSignedIn() -> Bool { + return ctxSpendService.isUserSignedIn + } } diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index 3a2321aaf..d930e5987 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "تجربة بديهية ومألوفة عبر جميع أجهزتك"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "خطأ"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "رصيد غير كاف"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "رسوم الشبكة"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "يرجى وضع هاتفك بالقرب من جهاز NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "يرجى النقر على الكلمات من عبارة الاسترداد بالترتيب الصحيح"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "شراء"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "إستقبال سريع"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "اظهر جملة الاسترداد"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "توضح هذه الخطوة الإضافية أنك تحاول حقًا إجراء معاملة."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "سيكون الرقم السري هذا مطلوبًا لإلغاء قفل تطبيقك في كل مرة تستخدمه."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index b7d5aeddf..979731597 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Интуитивно и познато преживяване на всичките Ви устройства"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Грешка"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Недостатъчно средства"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Невалидна сума"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Мрежа"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Мрежова такса"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Моля поставете вашият телефон близо до NFC устройство."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Моля, докоснете думите от фразата за възстановяване в правилния ред"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Бързо получаване"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Покажи фраза за възстановяване"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Този ПИН ще бъде необходим за отключване на приложението ви всеки път, когато го използвате."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index 0bda494cd..e1b1b557f 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Comissió de xarxa"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index 972921292..59e646437 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Intuitivní používání napříč všemi tvými zařízeními"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Chyba"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Při aktualizaci profilu se stala chyba"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Nedostatečný zůstatek"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Neplatná částka"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Neplatný QR kód"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Pozvání"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Síť"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Poplatek síti"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Přiložte váš telefon k zařízení NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Klepněte na slova z vaší fráze pro obnovení ve správném pořadí"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Přijmout"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Zobrazit frázi pro obnovení"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Tento PIN bude požadován pro odemčení aplikace pokaždé, když ji budete chtít použít."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index 095c07922..aaaf2bb00 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Fejl"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Netværksgebyr"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index 7fb7d473f..ff194201c 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Eine intuitive und gewohnte Erfahrung über alle Gerätetypen hinweg"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "und"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Fehler"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Fehler beim Updaten deines Profils"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gutscheinkarte"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Guthaben nicht ausreichend"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Ungültiger Betrag"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Ungültige Dash Adresse"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Ungültiger QR-Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Einladung"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Netzwerk"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Netzwerk-Gebühr"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Nicht festgelegt"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Bitte halte dein Telefon nahe an das NFC-Gerät."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Bitte tippe die Wörter deiner Wiederherstellungsphrase in der richtigen Reihenfolge an"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Kaufen"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Schnell Empfangen"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Wiederherstellungsphrase anzeigen"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Signiere die Nachricht."; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Dieser zusätzliche Schritt beweist, dass es wirklich du bist der die Transaktion ausführt."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Die PIN muss bei jedem Verwenden der App zum Entsperren eingegeben werden."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Du musst 5 Minuten warten, bevor du die nächste Auszahlung beginnen kannst."; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 969cb145f..3958be7e6 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Μια διαισθητική και οικεία εμπειρία σε όλες τις συσκευές σας"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "και"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Σφάλμα"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Σφάλμα ενημέρωσης του προφίλ σας"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Δωροκάρτα"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Ανεπαρκή χρήματα"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Ανεπαρκές ποσό"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Μη έγκυρη διεύθυνση Dash!"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Μη έγκυρος κωδικός QR"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Πρόσκληση"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Δίκτυο"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Τέλος δικτύου"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Δεν έχει καθοριστεί"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Τοποθετήστε το τηλέφωνό σας κοντά στη συσκευή NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Πατήστε στις λέξεις από τη φράση ανάκτησης σας με τη σωστή σειρά"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Αγορά"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Γρήγορη Λήψη"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Προβολή Φράσης Ανάκτησης"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Υπογράψτε το μήνυμα"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Αυτό το επιπλέον βήμα δείχνει ότι πραγματικά προσπαθείτε να κάνετε μια συναλλαγή."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Αυτός ο κωδικός PIN θα χρειαστεί να ξεκλειδώσετε την εφαρμογή σας κάθε φορά που την χρησιμοποιείτε."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Πρέπει να περιμένετε 5 λεπτά πριν ξεκινήσετε άλλη ανάληψη."; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index 52a625214..fe25ea82f 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index 68bef653b..bc25bf424 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Eraro"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index 350908f86..1cbd7f5ab 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Una experiencia intuitiva y familiar a través de todos tus dispositivos"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "y"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error al actualizar tu perfil"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Tarjeta de regalo"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Fondos insuficientes"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Monto inválido"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Dirección inválida de Dash"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Codigo QR invalido"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitación "; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Red de trabajo"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Comisión de red"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "No determinado"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Coloca tu teléfono cerca del dispositivo NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Por favor escribe las palabras de tu frase de recuperación en el orden correcto"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Compra"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Recibir Rápidamente "; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Mostrar Frase de Recuperación"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Firmar el mensaje"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Este paso adicional muestra que realmente eres tú quien intenta realizar una transacción."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Este PIN será requerido para desbloquear tu app cada vez que la utilices."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Debes esperar 5 minutos antes de iniciar otro retiro."; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index 2881cf5e8..860b283c0 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index 7b643a408..0cd988e95 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "تجربه‌ای ساده و آشنا روی همه دستگاه‌ها"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "خطا"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "موجودی ناکافی"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "کارمزد شبکه"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "لطفا این کلمات را بر اساس ترتیب کلمات در عبارت بازیابی، به ترتیب انتخاب کنید. "; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "خرید"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "دریافت سریع"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "نشان دادن عبارت بازیابی"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "این گام اضافه نشان می‌دهد واقعا خودتان قصد انجام این تراکنش را دارید. "; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "برای هر بار باز کردن قفل اپلیکیشن در مواقع استفاده، به این پین کد نیاز خواهید داشت."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index db5c3547a..797cfd1d2 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Virhe"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Verkon maksukulu"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index ab17b7aca..c2c874c1f 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Ang sapantaha at pamilyar na karanasan sa lahat ng iyong aparato"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "at"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Mali"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error sa pag-update ng iyong profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Hindi sapat na pondo"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Hindi wasto ang iyong Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Hindi wasto ang QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Imbitasyon"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Hindi determinado"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Pakilagay ang iyong phone malapit sa NFC device"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Paki-pindot ang mga salita mula sa iyong recovery phrase sa tamang pagkakasunod-sunod."; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Bumili"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Tanggapin ng mabilis"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Ipakita ang recovery phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Lagdaan ang mensahe"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Ipinapakita ng karagdagang hakbang na ito na ikaw talaga ang sumusubok na gumawa ng transaksyon."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Ang PIN na ito ay kailangan upang i-unlock ang iyong app kapag nais gamitin."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Kailangan mong maghintay ng 5 minuto bago simulan ang isa pang withdrawal"; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index 67756eba5..118a7eb8c 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Une utilisation familière et intuitive sur tous vos appareils"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "et"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Erreur"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Erreur en modifiant votre profil"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Carte-cadeau"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Fonds insuffisants"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Montant invalide"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Adresse Dash non valide"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "QR-code non valide"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Réseau"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Frais de réseau"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Indéterminé"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Veuillez placer votre téléphone près de l'appareil NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Veuillez saisir les mots de votre phrase de récupération dans le bon ordre"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Achat"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Réception rapide"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Voir la phase de récupération"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Signer le message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Cette étape supplémentaire montre que c'est vraiment vous qui essaie de faire une transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Ce code PIN sera demandé pour déverrouiller votre app avant chaque utilisation."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Vous devez attendre 5 minutes avant de lancer un autre retrait"; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index 89c7a0356..6871221c6 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index b276036c8..0f1a8e4c3 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Hiba"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Hálózat"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Hálózati díj"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Helyezd a telefonod az NFC eszköz közelébe."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 84f23fb7f..46182352e 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Pengalaman intuitif dan akrab di semua perangkat Anda"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "dan"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Kesalahan"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Terjadi kesalahan saat memperbarui profil Anda"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Kartu ucapan"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Dana tidak mencukupi"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Jumlah tidak valid"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Alamat Dash Salah"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Kode QR tidak valid"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Undangan"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Jaringan"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Biaya jaringan"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Tidak ditentukan"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Silakan letakkan ponsel Anda di dekat perangkat NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Ketuk kata-kata dari frasa pemulihan Anda dalam urutan yang benar"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Beli"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Terima Cepat"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Tampilkan Frasa pemulihan"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Tandatangani pesan"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Langkah ekstra ini menunjukkan bahwa Anda benar-benar mencoba melakukan transaksi."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "PIN ini akan diperlukan untuk membuka kunci aplikasi Anda setiap kali saat Anda menggunakannya."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Anda harus menunggu 5 menit sebelum memulai penarikan lainnya"; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index 37f0e9f2d..e6d4da20f 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Un'esperienza intuitiva e familiare su tutti i tuoi dispositivi"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "e"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Errore"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Errore durante l'aggiornamento del tuo profilo "; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Fondi insufficenti"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Importo non valido"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Indirizzo Dash non valido"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "QR Code Non Valido"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invito"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Commissione di rete"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Non determinato"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Perfavore posiziona il tuo telefono vicino al dispositivo NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Si prega di toccare le parole dalla frase di recupero nel giusto ordine"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Acquisto"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Rapido Ricevi"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Mostra la frase di recupero"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Firma il messaggio"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Questo passaggio aggiuntivo mostra che stai davvero cercando di effettuare una transazione."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Questo PIN ti sarà richiesto per sbloccare l'app ogni volta che la usi."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Devi attendere 5 minuti prima di avviare un altro prelievo"; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index 1090aaa15..2b443f139 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "全てのデバイスで直感的かつ使いやすい使用感"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "および"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "エラー"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "プロフィールの更新エラー"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "ギフトカード"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "資金不足"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "無効な金額"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "無効なDashアドレス"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "無効なQRコード"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "招待状"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "ネットワーク"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "ネットワーク手数料"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "未定"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "あなたの携帯電話をNFCデバイスに近づけてください"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "リカバリーフレーズの言葉を正しい順番にタップしてください"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "購入"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "クイック入金"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "復元フレーズを表示する"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "メッセージに署名する"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "この追加ステップは、お客様が本当に取引を行おうとしていることを証明するために行われます。"; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "このアプリをアンロックして使用するときは必ずこのPINが必要となります"; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "5分間待ってから次の出金を開始しましょう"; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index 590b7e1a0..91251d91f 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "당신의 모든 기기에 걸친 직관적이고 친근한 경험"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "또한"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "오류"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "프로필 업데이트 오류"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "기프트 카드"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "잔액 부족"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "유효하지 않은 금액"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "유효하지 않은 대시 주소"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "유효하지 않은 QR 코드"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "초대"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "네트워크"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "네트워크 수수료"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "결정되지 않음"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "휴대 전화를 NFC 기기 가까이에 두십시오."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "올바른 방식으로 당신의 복원 문구의 단어를 탭하십시오"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "매수하기"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "빠른 송금 수령"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "복원 문구 확인하기"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "이 메시지에 서명하기"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "이 추가적 단계를 통해 거래를 시도하는 것이 본인임을 확인합니다."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "당신이 어플을 언락하실 때마다 이 PIN이 필요합니다."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "다음 출금을 요청하시기 전 5분을 대기하여야 합니다"; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index 0bc5a5667..8842f6320 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Грешка"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index 0fd3dc48b..b886b71ad 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index cd72fe8b6..47be8fba7 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Feil"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Nettverksgebyr"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index f805d66e4..db6ed0b05 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Een intuïtieve en vertrouwde ervaring op al je apparaten"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = " en "; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Fout"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Fout bij bijwerken van je profiel"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Cadeaukaart"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Ontoereikende fondsen"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Ongeldig bedrag"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "ongeldig Dash adres"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Ongeldige QR-code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Uitnodiging"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Netwerk"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Netwerkkosten"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Niet bepaald"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Houd a.u.b. je telefoon bij een NFC-apparaat"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Tik a.u.b. op de woorden van je herstelzin in de juiste volgorde"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Aanschaffen"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Snel Ontvangen"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Toon herstelzin"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Onderteken het bericht"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Deze extra stap laat zien dat jij het bent die een transactie probeert te doen."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Deze PIN is vereist om uw app elke keer te ontgrendelen wanneer u deze gebruikt."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Je moet 5 minuten wachten voordat je een nieuwe opname kunt uitvoeren"; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index c612dc381..a7250c467 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Intuicyjne i znane doświadczenie na wszystkich urządzeniach"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "i"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Błąd"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Wystąpił błąd podczas aktualizacji twojego profilu"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Karta podarunkowa"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Niewystarczająca ilość funduszy"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Niewłaściwa ilość"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Nieprawidłowy adres Dash"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Niewłaściwy kod QR"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Zaproszenie"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Sieć"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Opłata sieci"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Nieustalony"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Przyłóż telefon do urządzenia NFC "; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Wskaź słowa z frazy odzyskiwania w odpowiedniej kolejności"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Kup"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Szybki Odbierz"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Pokaż Frazy Odzyskiwania Portfela"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Podpisz wiadomość"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Ten dodatkowy krok potwierdza, że to naprawdę ty dokonujesz tej transakcji. "; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Ten kod PIN będzie wymagany do odblokowania Twojej aplikacji za każdym razem, gdy z niej korzystasz."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Musisz odczekać 5 minut przed rozpoczęciem kolejnej wypłaty"; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index 160dba08c..ba0f1ec34 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Uma experiência familiar e através de todos os seus dispositivos"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "e"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Erro"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Erro ao atualizar seu perfil"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Vale-presente"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Fundos insuficientes"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Valor inválido"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Endereço Dash inválido"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "QR Code Inválido"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Convite"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Rede"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Taxa de rede"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Não determinado"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Por favor coloque seu telefone perto do dispositivo NFC"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Por favor, toque as palavras da sua frase de recuperação na ordem correta"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Comprar"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Receber Rapidamente"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Mostrar Frase de Recuperação"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Assine a mensagem"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Esta etapa extra mostra que é realmente você tentando fazer uma transação."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Este PIN será requerido para desbloquear o seu app toda vez que o utilize"; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Você precisa aguardar 5 minutos antes de iniciar outro saque"; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index e272d49f9..c82060905 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Eroare"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Fonduri nesuficiente"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Suma nevalidă"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Rețea"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Taxă de reţea"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Plasează telefonul în apropierea dispozitivului NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index e4af7a4da..b3cb4bcfe 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Интуитивный и привычный интерфейс на всех ваших устройствах"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = " и "; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Ошибка"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Ошибка при обновлении профиля"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Подарочный сертификат"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Недостаточно средств"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Некорректная сумма"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Некорректный адрес Dash"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Некорректный QR-код"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Приглашение"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Сеть"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Комиссия сети"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Не определён"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Пожалуйста, поместите Ваш телефон рядом с NFC устройством."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Пожалуйста, нажмите на слова из Вашей фразы восстановления в правильном порядке"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Купить"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Получить быстро"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Показать фразу восстановления"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Подписать сообщение"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Этот дополнительный шаг подтверждает, что транзакцию совершаете именно вы."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Этот PIN нужно будет вводить для разблокировки приложения при каждом его использовании."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Вы должны подождать 5 минут, прежде чем вывести средства ещё раз"; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index b91191539..4324d8ea4 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Intuitívny a známy zážitok vo všetkých vašich zariadeniach"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "a"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Chyba"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Pri aktualizácii vášho profilu sa vyskytla chyba"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Darčeková karta"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Nedostatok prostriedkov"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Neplatná suma"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Neplatná Dash adresa"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Neplatný QR kód"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Pozvánka"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Sieť"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Sieťový poplatok "; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Neurčené"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Umiestnite váš telefón blízko NFC zariadenia."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Klepnite na slová z obnovovacej frázy v správnom poradí"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Nákup"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Rýchlo prijať"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Zobraziť frázu obnovenia"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Podpísať správu"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Tento dodatočný krok potvrdzuje, že ste to skutočne vy kto sa pokúša uskutočniť transakciu."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Tento PIN bude potrebný na odomknutie aplikácie pri každom použití."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Pred ďalším výberom musíte počkať 5 minút"; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index e932bb870..5acc72609 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Napaka"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Omrežna provizija"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index 2fbddab19..e5366eef7 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index 1d347c75c..557abfe87 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Gabim"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Tarifa e rrjetit"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 2d06e5edd..78937522a 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Greška"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Mrežna provizija"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Molimo vas da postavite vaš telefon blizu NFC uređaja."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index dfea0b4b0..f9ac86744 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Fel"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Nätverk"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Nätverksavgift"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Please place your phone near NFC device."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index 1f77d0b73..e5540e2ad 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "ประสบการณ์ที่ใช้งานง่ายและคุ้นเคย"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "และ"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "ผิดพลาด"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "ข้อผิดพลาดในการอัปเดตโปรไฟล์ของคุณ"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "บัตรของขวัญ"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "ยอดเงินไม่เพียงพอ"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "จำนวนเงินไม่ถูกต้อง"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "ที่อยู่ Dash ไม่ถูกต้อง"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "QR Code ไม่ถูกต้อง"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "คำเชิญ"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "เครือข่าย"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "ค่าธรรมเนียมเครือข่าย"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "ไม่ได้กำหนด"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "โปรดวางมือถือของคุณใกล้กับอุปกรณ์ NFC"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "โปรดแตะที่คำจากวลีการกู้คืนของคุณในลำดับที่ถูกต้อง"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "ซื้อ"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "ได้รับอย่างรวดเร็ว"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "แสดงวลีกู้คืน"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "ลงชื่อเข้าใช้ข้อความ"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "ขั้นตอนพิเศษนี้แสดงให้เห็นว่าคุณพยายามทำธุรกรรม"; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "ต้องใช้ PIN นี้เพื่อปลดล็อคแอพของคุณทุกครั้งที่ใช้"; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 990403209..9b08c5f89 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Tüm cihazlarınızda tanıdık sezgisel bir deneyim"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "ve"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Hata"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Profiliniz güncellenirken hata oluştu"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Hediye Kartı"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Yetersiz bakiye"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Geçersiz tutar"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Geçersiz Dash adresi"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Geçersiz QR Kodu"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Davetiye"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Ağ"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Ağ ücreti"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Belirlenmedi"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Lütfen telefonunuzu bir NFC cihazının yakınına yerleştirin."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Lütfen kurtarma sözcük grubunuzu doğru şekilde sıralayın"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Satın alma"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Hızlı Al"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Kurtarma Sözcük Grubunu Göster"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Mesajı imzala"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Bu ekstra adım, gerçekten bir işlem yapmaya çalıştığınızı gösterir."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Bu PİN uygulamanın açılması için her zaman gerekecektir."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Başka bir para çekme işlemine başlamadan önce 5 dakika beklemeniz gerekir"; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index ad5362289..14990bab0 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Інтуїтивний та звичний інтерфейс на всіх ваших пристроях"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "і"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Помилка"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Помилка оновлення профіля"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Подарункова карта"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Недостатньо коштів"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Неправильна сума"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Неправильна Dash адреса"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Неправильний QR код"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Запрошення"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Мережа"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Комісія мережі"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Не визначено"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Розташуйте телефон біля пристрою NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Будь ласка, торкніться слів з вашої фрази відновлення в правильному порядку"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Покупка"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Швидке отримання"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Показати фразу відновлення"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Підпишіть повідомлення"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "Цей додатковий крок показує, що справді ви намагаєтеся здійснити транзакцію."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Цей PIN-код необхідний, щоб розблокувати вашу програму кожного разу, коли ви її використовуєте."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "Вам потрібно зачекати 5 хвилин, перш ніж почати наступне виведення"; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index ae2e8683f..2d0e104b3 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "Một giao diện trực quan và quen thuộc trên tất cả các thiết bị của bạn"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Lỗi"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Không đủ tiền"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Số tiền không hợp lệ"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Mã QR không hợp lệ"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Mạng"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Phí giao dịch"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "Hãy đặt điện thoại của bạn cạnh thiết bị NFC."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Hãy bấm vào những từ trong cụm từ phục hồi của bạn theo một thứ tự đúng"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Nhận nhanh"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Hiển thị câu phục hồi"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "Mã PIN này sẽ được hỏi để mở ứng dụng của bạn mỗi khi bạn sử dụng nó."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index a9eb5860d..50a73f025 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "请将你的手机靠近NFC设备."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index b0b3c8cb5..f16b553bb 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "An intuitive and familiar experience across all your devices"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "and"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "Error"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "Gift Card"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "Insufficient funds"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "Invalid amount"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "Invalid Dash address"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "Invalid QR Code"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "Invitation"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "Network"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "Network fee"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "Not Determined"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "請將手機放在NFC設備附近。"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "Please tap on the words from your recovery phrase in the right order"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "Purchase"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "Quick Receive"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "Show Recovery Phrase"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "Sign the message"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "This extra step shows it’s really you trying to make a transaction."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "This PIN will be required to unlock your app every time when you use it."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "You need to wait 5 minutes before initiating another withdrawal"; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index 6ad10d0be..01725e959 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "所有设备上的直观熟悉体验"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "和"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "错误"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "更新您个人资料时出错"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "礼品卡"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "资金不足"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "无效数额"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "无效的Dash地址"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "无效二维码"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "邀请"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "网络"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "网络手续费"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "尚未确定"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "请将您的手机靠近NFC设备."; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "请以正确顺序输入您的助记词"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "购买"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "快速接收"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "显示助记词"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "签名信息"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "此额外步骤用来证明真的是您在尝试进行交易."; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "每次使用时都需要输入PIN以解锁您的app."; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "您需要等待5分钟才能再次发起提现"; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index 8ccee2ecd..9b32b42c6 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -211,6 +211,9 @@ /* No comment provided by engineer. */ "An intuitive and familiar experience across all your devices" = "跨所有設備的直觀熟悉的體驗"; +/* CTXSpend error */ +"An unknown error occurred. Please try again later." = "An unknown error occurred. Please try again later."; + /* CrowdNode */ "and" = "和"; @@ -841,6 +844,9 @@ /* No comment provided by engineer. */ "Error" = "錯誤"; +/* CTXSpend error */ +"Error processing server response. Please try again later." = "Error processing server response. Please try again later."; + /* No comment provided by engineer. */ "Error updating your profile" = "更新您的個人資料時出錯"; @@ -1018,6 +1024,9 @@ /* Explore Dash: Filters */ "Gift Card" = "禮物卡"; +/* DashSpend */ +"Gift card purchase successful" = "Gift card purchase successful"; + /* DashSpend confirmation */ "Gift card total" = "Gift card total"; @@ -1171,6 +1180,9 @@ /* No comment provided by engineer. */ "Insufficient funds" = "餘額不足"; +/* CTXSpend error */ +"Insufficient funds to complete this purchase." = "Insufficient funds to complete this purchase."; + /* Send screen */ "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction." = "Insufficient mixed funds. Wait for CoinJoin mixing to finish or disable this feature in the settings to complete this transaction."; @@ -1201,6 +1213,9 @@ /* Balance */ "Invalid amount" = "金額無效"; +/* CTXSpend error */ +"Invalid amount. Please check merchant limits." = "Invalid amount. Please check merchant limits."; + /* No comment provided by engineer. */ "Invalid Dash address" = "無效的達世幣位址"; @@ -1219,6 +1234,9 @@ /* No comment provided by engineer. */ "Invalid QR Code" = "無效的二維碼"; +/* CTXSpend error */ +"Invalid verification code. Please try again." = "Invalid verification code. Please try again."; + /* No comment provided by engineer. */ "Invitation" = "邀請"; @@ -1556,6 +1574,9 @@ /* No comment provided by engineer. */ "Network" = "網絡"; +/* CTXSpend error */ +"Network error. Please check your connection and try again." = "Network error. Please check your connection and try again."; + /* No comment provided by engineer. */ "Network fee" = "網絡費用"; @@ -1625,9 +1646,6 @@ /* Location Service Status */ "Not Determined" = "尚未決定"; -/* No comment provided by engineer. */ -"Not implemented" = "Not implemented"; - /* CoinJoin */ "Not started" = "Not started"; @@ -1808,6 +1826,9 @@ /* No comment provided by engineer. */ "Please place your phone near NFC device." = "請將手機放在NFC設備附近。"; +/* CTXSpend error */ +"Please sign in to your DashSpend account." = "Please sign in to your DashSpend account."; + /* No comment provided by engineer. */ "Please tap on the words from your recovery phrase in the right order" = "請以正確的順序點按您的恢復詞組中的單詞"; @@ -1886,6 +1907,9 @@ /* Coinbase/Buy Dash */ "Purchase" = "購買"; +/* Alert title */ +"Purchase Failed" = "Purchase Failed"; + /* No comment provided by engineer. */ "Quick Receive" = "快速接收"; @@ -2224,6 +2248,9 @@ /* No comment provided by engineer. */ "Show Recovery Phrase" = "顯示恢復詞組"; +/* Alert title */ +"Sign in required" = "Sign in required"; + /* CrowdNode */ "Sign the message" = "簽署訊息"; @@ -2407,6 +2434,9 @@ /* Coinbase Two Factor Auth */ "This extra step shows it’s really you trying to make a transaction." = "這個額外的步驟用來證明真的是你在嘗試進行交易。"; +/* CTXSpend error */ +"This merchant is currently unavailable." = "This merchant is currently unavailable."; + /* No comment provided by engineer. */ "This PIN will be required to unlock your app every time when you use it." = "每次使用時,都需要使用此密碼來解鎖您的應用程式。"; @@ -2920,6 +2950,9 @@ /* Usernames */ "You need to have more than %@ Dash to create a username" = "You need to have more than %@ Dash to create a username"; +/* DashSpend */ +"You need to sign in to DashSpend to purchase gift cards." = "You need to sign in to DashSpend to purchase gift cards."; + /* CrowdNode */ "You need to wait 5 minutes before initiating another withdrawal" = "您需要等待5分鐘才能再次發起提款"; From c7cef2fa034ea9ab4a5a17a76e4ca83f8dfc5372 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Sat, 24 May 2025 21:21:49 +0700 Subject: [PATCH 04/10] feat: payment flow draft --- DashSyncCurrentCommit | 2 +- DashWallet.xcodeproj/project.pbxproj | 12 +- .../Explore Dash/Model/CTXSpendModels.swift | 68 ------- .../Model/Entites/CTXSpendModels.swift | 107 ++++++++--- .../Explore Dash/Services/CTXSpendAPI.swift | 3 + .../Services/CTXSpendService.swift | 4 +- .../Views/DashSpend/DashSpendPayScreen.swift | 181 +++++++++++++++--- .../DashSpend/DashSpendPayViewModel.swift | 29 ++- 8 files changed, 259 insertions(+), 147 deletions(-) delete mode 100644 DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift diff --git a/DashSyncCurrentCommit b/DashSyncCurrentCommit index cea1bde48..2894cace6 100644 --- a/DashSyncCurrentCommit +++ b/DashSyncCurrentCommit @@ -1 +1 @@ -b6a82ef4d57754d29599b794df3274e4cd36e07a +fdf97505762702eb6290d71c61a93c8f6a57e3ba diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index 0f2332fda..05fc917c7 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -551,6 +551,8 @@ 753261AE2CBC1040003CDE00 /* InvitationFlowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753261AD2CBC1040003CDE00 /* InvitationFlowViewController.swift */; }; 753261B02CBC11BF003CDE00 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753261AF2CBC11BF003CDE00 /* WelcomeViewController.swift */; }; 753261B22CBC157F003CDE00 /* GetStartedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753261B12CBC157F003CDE00 /* GetStartedViewController.swift */; }; + 753E46E82DE1E24300A3FF2A /* CTXSpendModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753E46E72DE1E24300A3FF2A /* CTXSpendModels.swift */; }; + 753E46E92DE1E24300A3FF2A /* CTXSpendModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753E46E72DE1E24300A3FF2A /* CTXSpendModels.swift */; }; 753F75342DD0D42300D40DFE /* DashSpendPayScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753F75332DD0D41900D40DFE /* DashSpendPayScreen.swift */; }; 753F75352DD0D42300D40DFE /* DashSpendPayScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753F75332DD0D41900D40DFE /* DashSpendPayScreen.swift */; }; 753F75372DD0D76400D40DFE /* DashSpendPayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753F75362DD0D75F00D40DFE /* DashSpendPayViewModel.swift */; }; @@ -564,11 +566,9 @@ 754495DD2AE91B6300492817 /* GroupedRequestCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754495DC2AE91B6300492817 /* GroupedRequestCell.swift */; }; 754495DF2AE91D3500492817 /* UsernameRequestCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754495DE2AE91D3500492817 /* UsernameRequestCell.swift */; }; 754565C82DAA52A000DA4E8E /* CTXSpendAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C42DAA52A000DA4E8E /* CTXSpendAPI.swift */; }; - 754565C92DAA52A000DA4E8E /* CTXSpendModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C62DAA52A000DA4E8E /* CTXSpendModels.swift */; }; 754565CA2DAA52A000DA4E8E /* CTXSpendService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C72DAA52A000DA4E8E /* CTXSpendService.swift */; }; 754565CB2DAA52A000DA4E8E /* CTXSpendEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C52DAA52A000DA4E8E /* CTXSpendEndpoint.swift */; }; 754565CC2DAA52A000DA4E8E /* CTXSpendAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C42DAA52A000DA4E8E /* CTXSpendAPI.swift */; }; - 754565CD2DAA52A000DA4E8E /* CTXSpendModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C62DAA52A000DA4E8E /* CTXSpendModels.swift */; }; 754565CE2DAA52A000DA4E8E /* CTXSpendService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C72DAA52A000DA4E8E /* CTXSpendService.swift */; }; 754565CF2DAA52A000DA4E8E /* CTXSpendEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565C52DAA52A000DA4E8E /* CTXSpendEndpoint.swift */; }; 754565D12DABA5F300DA4E8E /* MerchantTypesDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565D02DABA5EB00DA4E8E /* MerchantTypesDialog.swift */; }; @@ -2452,6 +2452,7 @@ 753261AD2CBC1040003CDE00 /* InvitationFlowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitationFlowViewController.swift; sourceTree = ""; }; 753261AF2CBC11BF003CDE00 /* WelcomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = ""; }; 753261B12CBC157F003CDE00 /* GetStartedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetStartedViewController.swift; sourceTree = ""; }; + 753E46E72DE1E24300A3FF2A /* CTXSpendModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendModels.swift; sourceTree = ""; }; 753F75332DD0D41900D40DFE /* DashSpendPayScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSpendPayScreen.swift; sourceTree = ""; }; 753F75362DD0D75F00D40DFE /* DashSpendPayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSpendPayViewModel.swift; sourceTree = ""; }; 753FD7E12CA44BDD00B7751F /* CoinJoinProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinJoinProgress.swift; sourceTree = ""; }; @@ -2462,7 +2463,6 @@ 754495DE2AE91D3500492817 /* UsernameRequestCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsernameRequestCell.swift; sourceTree = ""; }; 754565C42DAA52A000DA4E8E /* CTXSpendAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendAPI.swift; sourceTree = ""; }; 754565C52DAA52A000DA4E8E /* CTXSpendEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendEndpoint.swift; sourceTree = ""; }; - 754565C62DAA52A000DA4E8E /* CTXSpendModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendModels.swift; sourceTree = ""; }; 754565C72DAA52A000DA4E8E /* CTXSpendService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendService.swift; sourceTree = ""; }; 754565D02DABA5EB00DA4E8E /* MerchantTypesDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantTypesDialog.swift; sourceTree = ""; }; 754565D32DAD0F5B00DA4E8E /* DWExploreTestnetViewController+DashWallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DWExploreTestnetViewController+DashWallet.swift"; sourceTree = ""; }; @@ -5666,7 +5666,7 @@ 47AE8B9A28BFAD2000490F5E /* Entites */ = { isa = PBXGroup; children = ( - 754565C62DAA52A000DA4E8E /* CTXSpendModels.swift */, + 753E46E72DE1E24300A3FF2A /* CTXSpendModels.swift */, 47AE8B9B28BFAD2800490F5E /* ExplorePointOfUse.swift */, ); path = Entites; @@ -8836,7 +8836,6 @@ 47838B7D290133610003E8AB /* PointOfUseListFiltersViewController.swift in Sources */, 47AE8C1A28C6A21A00490F5E /* AllMerchantLocationsDataProvider.swift in Sources */, 754565CC2DAA52A000DA4E8E /* CTXSpendAPI.swift in Sources */, - 754565CD2DAA52A000DA4E8E /* CTXSpendModels.swift in Sources */, 754565CE2DAA52A000DA4E8E /* CTXSpendService.swift in Sources */, 754565CF2DAA52A000DA4E8E /* CTXSpendEndpoint.swift in Sources */, C9F451E52A0B986E00825057 /* MainTabbarController.swift in Sources */, @@ -8860,6 +8859,7 @@ C917023F29D44E0B008C034D /* SendReceivePageController.swift in Sources */, 753FD7E22CA44BDD00B7751F /* CoinJoinProgress.swift in Sources */, 2A7A7BD92348CB7300451078 /* DWSettingsMenuModel.m in Sources */, + 753E46E82DE1E24300A3FF2A /* CTXSpendModels.swift in Sources */, 478A2C7228DC909C00AD1420 /* BaseNavigationController.swift in Sources */, 47CDEECC294A2BAD008AE06D /* UIViewController+Coinbase.swift in Sources */, 472D13E1299E1F2F006903F1 /* CSVBuilder.swift in Sources */, @@ -9575,6 +9575,7 @@ C943B5122A40A54600AF23C5 /* DWInvitationHistoryModel.m in Sources */, C943B31A2A408CED00AF23C5 /* DWCurrentUserProfileView.m in Sources */, 751B61C22ADFF99D00D1C2EF /* CoinbaseDepositResponse.swift in Sources */, + 753E46E92DE1E24300A3FF2A /* CTXSpendModels.swift in Sources */, C943B4F32A40A54600AF23C5 /* DWDPEstablishedContactObject.m in Sources */, C9D2C7E02A320AA000D15901 /* TransactionFilter.swift in Sources */, C9D2C7E22A320AA000D15901 /* CrowdNodeWithdrawalReceivedTx.swift in Sources */, @@ -9834,7 +9835,6 @@ C943B5382A40A65B00AF23C5 /* DWScrollingViewController.m in Sources */, C9D2C8B22A320AA000D15901 /* CoinbaseAccountAddress.swift in Sources */, 754565C82DAA52A000DA4E8E /* CTXSpendAPI.swift in Sources */, - 754565C92DAA52A000DA4E8E /* CTXSpendModels.swift in Sources */, 754565CA2DAA52A000DA4E8E /* CTXSpendService.swift in Sources */, 754565CB2DAA52A000DA4E8E /* CTXSpendEndpoint.swift in Sources */, C9D2C8B32A320AA000D15901 /* DWMainMenuTableViewCell.m in Sources */, diff --git a/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift deleted file mode 100644 index faef2576e..000000000 --- a/DashWallet/Sources/Models/Explore Dash/Model/CTXSpendModels.swift +++ /dev/null @@ -1,68 +0,0 @@ -import Foundation - -// MARK: - Request Models - -struct LoginRequest: Codable { - let email: String -} - -struct VerifyEmailRequest: Codable { - let email: String - let code: String -} - -struct PurchaseGiftCardRequest: Codable { - let cryptoCurrency: String - let fiatCurrency: String - let fiatAmount: String - let merchantId: String -} - -// MARK: - Response Models - -struct VerifyEmailResponse: Codable { - let accessToken: String - let refreshToken: String -} - -struct GiftCardResponse: Codable { - let cryptoCurrency: String - let fiatCurrency: String - let fiatAmount: String - let merchantName: String - let merchantId: String - let iconUrl: String? - let barcode: String? - let barcodeType: String? - let dashPaymentUrl: String - let dashAmount: String - let claimCode: String? - let status: String - let txid: String? - let createdAt: String -} - -struct MerchantResponse: Codable { - let id: String - let name: String - let website: String - let logoUrl: String - let enabled: Bool - let minimumCardPurchase: Double - let maximumCardPurchase: Double - let savingsPercentage: Double - let denominationType: DenominationType - let denominations: [Double] - - enum CodingKeys: String, CodingKey { - case id, name, website, enabled - case logoUrl = "logoLocation" - case minimumCardPurchase, maximumCardPurchase - case savingsPercentage, denominationType, denominations - } -} - -enum DenominationType: String, Codable { - case Range = "range" - case Fixed = "fixed" -} \ No newline at end of file diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift index c05635d0f..d47330755 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift @@ -1,28 +1,12 @@ -// -// 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 -// Request Models -public struct LoginRequest: Codable { +// MARK: - Request Models + +struct LoginRequest: Codable { let email: String } -public struct VerifyEmailRequest: Codable { +struct VerifyEmailRequest: Codable { let email: String let code: String } @@ -34,21 +18,82 @@ public struct PurchaseGiftCardRequest: Codable { let merchantId: String } -// Response Models -public struct VerifyEmailResponse: Codable { +// MARK: - Response Models + +struct VerifyEmailResponse: Codable { let accessToken: String let refreshToken: String } -public struct GiftCardResponse: Codable { - let giftCardId: String - let dashAmount: String - let dashTxUrl: String - let checkoutUrl: String +struct GiftCardResponse: Codable { + let id: String + let percentDiscount: String + let paymentCryptoAmount: String + let cardFiatAmount: String + let cardFiatCurrency: String + let paymentUrls: [String: String] + let paymentCryptoCurrency: String + let paymentCryptoNetwork: String + let paymentFiatCurrency: String + let userId: String + let merchantName: String + let userEmail: String + let created: String + let rate: String + let paymentFiatAmount: String + let status: String + let paymentId: String +} + +struct MerchantResponse: Codable { + let id: String + let name: String + let logoUrl: String + let enabled: Bool + let savingsPercentage: Int + let denominationsType: String + let denominations: [String] + let cachedLocationCount: Int + let mapPinUrl: String + let type: String + let redeemType: String + let info: MerchantInfo + let cardImageUrl: String + let currency: String + + // Computed properties for backward compatibility + var website: String { + return "" // This field doesn't exist in the response + } + + var minimumCardPurchase: Double { + guard denominations.count >= 1, let min = Double(denominations[0]) else { return 0.0 } + return min + } + + var maximumCardPurchase: Double { + guard denominations.count >= 2, let max = Double(denominations[1]) else { return 0.0 } + return max + } + + var denominationType: DenominationType { + switch denominationsType { + case "min-max": + return .Range + default: + return .Fixed + } + } +} + +struct MerchantInfo: Codable { + let terms: String + let description: String + let instructions: String + let intro: String } -public struct MerchantResponse: Codable { - let savingsPercentage: Double - let minimumCardPurchase: Double - let maximumCardPurchase: Double +enum DenominationType: String, Codable { + case Range = "range" + case Fixed = "fixed" } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift index fa5b6f9e0..e594f6616 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift @@ -27,6 +27,7 @@ enum CTXSpendError: Error, LocalizedError { case invalidMerchant case invalidAmount case unknown + case paymentProcessingError(String) public var errorDescription: String? { switch self { @@ -46,6 +47,8 @@ enum CTXSpendError: Error, LocalizedError { return NSLocalizedString("Invalid amount. Please check merchant limits.", comment: "CTXSpend error") case .unknown: return NSLocalizedString("An unknown error occurred. Please try again later.", comment: "CTXSpend error") + case .paymentProcessingError(let details): + return String(format: NSLocalizedString("Payment processing error: %@", comment: "CTXSpend error"), details) } } } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift index 1ba78963e..53e40c0c0 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift @@ -102,7 +102,7 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { ) do { - let response = try await CTXSpendAPI.shared.request(.purchaseGiftCard(request)) + let response: GiftCardResponse = try await CTXSpendAPI.shared.request(.purchaseGiftCard(request)) DSLogger.log("Gift card purchased successfully: \(response)") return response } catch let error as CTXSpendError { @@ -150,7 +150,7 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { func getMerchant(merchantId: String) async throws -> MerchantResponse { do { - let response = try await CTXSpendAPI.shared.request(.getMerchant(merchantId)) + let response: MerchantResponse = try await CTXSpendAPI.shared.request(.getMerchant(merchantId)) DSLogger.log("Successfully retrieved merchant info: \(merchantId)") return response } catch let error as CTXSpendError { diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 955fe54c4..8ef71f481 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -30,6 +30,10 @@ struct DashSpendPayScreen: View { @State private var errorMessage = "" @State private var errorTitle = "" + // Payment processor and delegate need to be retained for the duration of the payment + @State private var paymentProcessor: DWPaymentProcessor? + @State private var paymentDelegate: PaymentProcessorDelegate? + init(merchant: ExplorePointOfUse, justAuthenticated: Bool = false) { self.merchant = merchant self._viewModel = .init(wrappedValue: DashSpendPayViewModel(merchant: merchant)) @@ -81,7 +85,7 @@ struct DashSpendPayScreen: View { HStack { if viewModel.showLimits { - Text(viewModel.minimumLimit) + Text(viewModel.minimumLimitMessage) .font(.body2) .foregroundColor(Color.primaryText) .padding(.leading, 20) @@ -106,7 +110,7 @@ struct DashSpendPayScreen: View { if viewModel.showLimits { Spacer() - Text(viewModel.maximumimit) + Text(viewModel.maximumLimitMessage) .font(.body2) .foregroundColor(Color.primaryText) .padding(.trailing, 20) @@ -187,10 +191,13 @@ struct DashSpendPayScreen: View { } .onDisappear { viewModel.unsubscribeFromAll() + // Clean up payment processor if still active + paymentProcessor = nil + paymentDelegate = nil } .sheet(isPresented: $showConfirmationDialog) { let dialog = BottomSheet( - title: NSLocalizedString("Confirm", comment: "DashSpend confirmation dialog title"), + title: NSLocalizedString("Confirm", comment: "DashSpend"), showBackButton: Binding.constant(false) ) { ConfirmationDialog( @@ -227,33 +234,22 @@ struct DashSpendPayScreen: View { // Success! Show success message and log to console print("============ GIFT CARD PURCHASE SUCCESSFUL ============") print("Merchant: \(response.merchantName)") - print("Amount: \(response.fiatCurrency) \(response.fiatAmount)") - print("Dash Amount: \(response.dashAmount)") - print("Dash Payment URL: \(response.dashPaymentUrl)") - - if let claimCode = response.claimCode { - print("Claim Code: \(claimCode)") - } + print("Amount: \(response.paymentFiatCurrency) \(response.paymentFiatAmount)") + print("Dash Amount: \(response.paymentCryptoAmount)") + print("Dash Payment URL: \(response.paymentUrls.first)") - if let barcode = response.barcode { - print("Barcode: \(barcode)") - if let barcodeType = response.barcodeType { - print("Barcode Type: \(barcodeType)") - } - } - if let txid = response.txid { - print("Transaction ID: \(txid)") - } + print("paymentId: \(response.paymentId)") - print("Created At: \(response.createdAt)") + print("Created At: \(response.created)") print("Status: \(response.status)") print("====================================================") - showConfirmToast = true - DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - showConfirmToast = false - // In a real implementation, we would navigate to a gift card details screen + // Process the payment using the payment URL + if let paymentUrlString = response.paymentUrls.first { + await processPayment(with: paymentUrlString.value, paymentId: response.paymentId) + } else { + throw CTXSpendError.paymentProcessingError("No payment URL received") } } catch let error as CTXSpendError { errorTitle = NSLocalizedString("Purchase Failed", comment: "Alert title") @@ -271,6 +267,80 @@ struct DashSpendPayScreen: View { } } + private func processPayment(with paymentUrlString: String, paymentId: String) async { + do { + // Create payment input from the URL + guard let paymentUrl = URL(string: paymentUrlString) else { + throw CTXSpendError.paymentProcessingError("Invalid payment URL") + } + + // Use the existing payment infrastructure + let payModel = DWPayModel() + let paymentInput = payModel.paymentInput(with: paymentUrl) + + // If we have a BIP70 payment request URL, we need to fetch it first + if paymentInput.request?.r != nil { + try await fetchAndProcessPaymentRequest(paymentInput: paymentInput, paymentId: paymentId) + } else { + throw CTXSpendError.paymentProcessingError("Invalid payment request") + } + + } catch { + errorTitle = NSLocalizedString("Payment Error", comment: "Alert title") + errorMessage = error.localizedDescription + showErrorDialog = true + } + } + + private func fetchAndProcessPaymentRequest(paymentInput: DWPaymentInput, paymentId: String) async throws { + return try await withCheckedThrowingContinuation { continuation in + // Store the completion for later use + let completion: (DSTransaction?, Error?) -> Void = { transaction, error in + DispatchQueue.main.async { + if let error = error { + continuation.resume(throwing: error) + } else if let transaction = transaction { + // Payment successful + print("Payment transaction completed: \(transaction.txHashHexString)") + + // Save gift card information + self.viewModel.saveGiftCardDummy( + txHashData: transaction.txHashData, + giftCardId: paymentId + ) + + self.showConfirmToast = true + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + self.showConfirmToast = false + self.presentationMode.wrappedValue.dismiss() + } + + continuation.resume() + } else { + continuation.resume(throwing: CTXSpendError.paymentProcessingError("No transaction returned")) + } + + // Clean up the payment processor and delegate after completion + self.paymentProcessor = nil + self.paymentDelegate = nil + } + } + + // Create and retain the delegate and processor + let delegate = PaymentProcessorDelegate(completion: completion) + let processor = DWPaymentProcessor(delegate: delegate) + + // Store them in instance variables to keep them alive + self.paymentDelegate = delegate + self.paymentProcessor = processor + + // Process the payment on the main thread + DispatchQueue.main.async { + processor.processPaymentInput(paymentInput) + } + } + } + private func showSignInError() { errorTitle = NSLocalizedString("Sign in required", comment: "Alert title") errorMessage = NSLocalizedString("You need to sign in to DashSpend to purchase gift cards.", comment: "DashSpend") @@ -419,3 +489,66 @@ struct ConfirmationDialog: View { .edgesIgnoringSafeArea(.bottom) } } + +// MARK: - PaymentProcessorDelegate + +class PaymentProcessorDelegate: NSObject, DWPaymentProcessorDelegate { + private let completion: (DSTransaction?, Error?) -> Void + + init(completion: @escaping (DSTransaction?, Error?) -> Void) { + self.completion = completion + } + + func paymentProcessor(_ processor: DWPaymentProcessor, didSend protocolRequest: DSPaymentProtocolRequest, transaction: DSTransaction, contactItem: DWDPBasicUserItem?) { + completion(transaction, nil) + } + + func paymentProcessor(_ processor: DWPaymentProcessor, didFailWithError error: Error?, title: String?, message: String?) { + let fullError = NSError( + domain: "DashSpend", + code: -1, + userInfo: [ + NSLocalizedDescriptionKey: message ?? title ?? NSLocalizedString("Payment failed", comment: "") + ] + ) + completion(nil, error ?? fullError) + } + + func paymentProcessor(_ processor: DWPaymentProcessor, requestAmountWithDestination sendingDestination: String, details: DSPaymentProtocolDetails?, contactItem: DWDPBasicUserItem?) { + // Not needed for our use case + } + + func paymentProcessor(_ processor: DWPaymentProcessor, requestUserActionTitle title: String?, message: String?, actionTitle: String, cancel cancelBlock: (() -> Void)?, actionBlock: (() -> Void)?) { + // Auto-confirm for gift card purchases + actionBlock?() + } + + func paymentProcessor(_ processor: DWPaymentProcessor, confirmPaymentOutput paymentOutput: DWPaymentOutput) { + // Auto-confirm for gift card purchases + processor.confirmPaymentOutput(paymentOutput) + } + + func paymentProcessorDidCancelTransactionSigning(_ processor: DWPaymentProcessor) { + completion(nil, NSError(domain: "DashSpend", code: -2, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Transaction cancelled", comment: "")])) + } + + func paymentProcessor(_ processor: DWPaymentProcessor, didSweepRequest protocolRequest: DSPaymentRequest, transaction: DSTransaction) { + completion(transaction, nil) + } + + func paymentProcessor(_ processor: DWPaymentProcessor, displayFileProcessResult result: String) { + // Not needed for our use case + } + + func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { + // Not needed for our use case + } + + func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { + // Could show progress indicator here if needed + } + + func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { + // Could hide progress indicator here if needed + } +} diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 4ea69c1d6..62f5c3719 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -26,8 +26,6 @@ class DashSpendPayViewModel: ObservableObject { private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: defaultCurrency) private let ctxSpendService = CTXSpendService.shared - private let minimumAmount: Decimal = 5 // TODO: limits - private let maximumAmount: Decimal = 50 private(set) var amount: Decimal = 0 private(set) var savingsFraction: Decimal = 0.0 @Published private(set) var isLoading = false @@ -41,6 +39,8 @@ class DashSpendPayViewModel: ObservableObject { @Published var merchantIconUrl: String = "" @Published var walletBalance: UInt64 = 0 @Published var coinJoinBalance: UInt64 = 0 + @Published var minimumAmount: Decimal = 0 + @Published var maximumAmount: Decimal = 0 @Published var error: Error? = nil @Published var input: String = "0" { didSet { @@ -80,8 +80,8 @@ class DashSpendPayViewModel: ObservableObject { } var showCost: Bool { error == nil && amount >= minimumAmount && amount <= maximumAmount } var showLimits: Bool { error == nil && !showCost } - var minimumLimit: String { String.localizedStringWithFormat(NSLocalizedString("Min: %@", comment: "DashSpend"), fiatFormatter.string(for: minimumAmount) ?? "0.0" ) } - var maximumimit: String { String.localizedStringWithFormat(NSLocalizedString("Max: %@", comment: "DashSpend"), fiatFormatter.string(for: maximumAmount) ?? "0.0" ) } + var minimumLimitMessage: String { String.localizedStringWithFormat(NSLocalizedString("Min: %@", comment: "DashSpend"), fiatFormatter.string(for: minimumAmount) ?? "0.0" ) } + 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) { @@ -183,7 +183,7 @@ class DashSpendPayViewModel: ObservableObject { defer { isLoading = false } do { - let fiatAmountString = String(format: "%.2f", amount) + let fiatAmountString = String(format: "%.2f", Double(truncating: amount as NSDecimalNumber)) DSLogger.log("Making API request to purchase gift card: merchantId=\(merchantId), amount=\(fiatAmountString)USD") let response = try await ctxSpendService.purchaseGiftCard( @@ -193,16 +193,6 @@ class DashSpendPayViewModel: ObservableObject { cryptoCurrency: "DASH" ) - // Log success details - DSLogger.log("Gift card purchase successful!") - DSLogger.log("Response details: Merchant=\(response.merchantName), Amount=\(response.fiatAmount) \(response.fiatCurrency)") - DSLogger.log("DASH Amount: \(response.dashAmount)") - DSLogger.log("DASH Payment URL: \(response.dashPaymentUrl)") - - if let txid = response.txid { - DSLogger.log("Transaction ID: \(txid)") - } - return response } catch { DSLogger.log("Gift card purchase failed with error: \(error)") @@ -213,4 +203,13 @@ class DashSpendPayViewModel: ObservableObject { func isUserSignedIn() -> Bool { return ctxSpendService.isUserSignedIn } + + func saveGiftCardDummy(txHashData: Data, giftCardId: String) { + // TODO: Implement gift card storage in iOS + // For now, just log the information + DSLogger.log("Gift card saved - txId: \(txHashData.hexEncodedString()), giftCardId: \(giftCardId)") + + // In a full implementation, this would save to Core Data or UserDefaults + // Similar to how the Android version saves to a Room database + } } From feebdc8d15e88e3f0481d37fd42c8408db590537 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Sun, 25 May 2025 15:17:14 +0700 Subject: [PATCH 05/10] feat: dashspend payment flow --- DashWallet.xcodeproj/project.pbxproj | 8 +- .../CrowdNode/Services/SendCoinsService.swift | 66 ---- .../Model/Entites/CTXSpendModels.swift | 5 - .../Transactions/SendCoinsService.swift | 180 ++++++++++ .../DashSpend/CTXSpendUserAuthScreen.swift | 1 + .../DashSpendConfirmationDialog.swift | 161 +++++++++ .../Views/DashSpend/DashSpendPayScreen.swift | 331 +----------------- .../DashSpend/DashSpendPayViewModel.swift | 70 ++-- .../ProvideAmountViewController.swift | 6 +- .../NumericKeyboardView.swift | 5 + DashWallet/ar.lproj/Localizable.strings | 9 + DashWallet/bg.lproj/Localizable.strings | 9 + DashWallet/ca.lproj/Localizable.strings | 9 + DashWallet/cs.lproj/Localizable.strings | 9 + DashWallet/da.lproj/Localizable.strings | 9 + DashWallet/de.lproj/Localizable.strings | 9 + DashWallet/el.lproj/Localizable.strings | 9 + DashWallet/en.lproj/Localizable.strings | 9 + DashWallet/eo.lproj/Localizable.strings | 9 + DashWallet/es.lproj/Localizable.strings | 9 + DashWallet/et.lproj/Localizable.strings | 9 + DashWallet/fa.lproj/Localizable.strings | 9 + DashWallet/fi.lproj/Localizable.strings | 9 + DashWallet/fil.lproj/Localizable.strings | 9 + DashWallet/fr.lproj/Localizable.strings | 9 + DashWallet/hr.lproj/Localizable.strings | 9 + DashWallet/hu.lproj/Localizable.strings | 9 + DashWallet/id.lproj/Localizable.strings | 9 + DashWallet/it.lproj/Localizable.strings | 9 + DashWallet/ja.lproj/Localizable.strings | 9 + DashWallet/ko.lproj/Localizable.strings | 9 + DashWallet/mk.lproj/Localizable.strings | 9 + DashWallet/ms.lproj/Localizable.strings | 9 + DashWallet/nb.lproj/Localizable.strings | 9 + DashWallet/nl.lproj/Localizable.strings | 9 + DashWallet/pl.lproj/Localizable.strings | 9 + DashWallet/pt.lproj/Localizable.strings | 9 + DashWallet/ro.lproj/Localizable.strings | 9 + DashWallet/ru.lproj/Localizable.strings | 9 + DashWallet/sk.lproj/Localizable.strings | 9 + DashWallet/sl.lproj/Localizable.strings | 9 + DashWallet/sl_SI.lproj/Localizable.strings | 9 + DashWallet/sq.lproj/Localizable.strings | 9 + DashWallet/sr.lproj/Localizable.strings | 9 + DashWallet/sv.lproj/Localizable.strings | 9 + DashWallet/th.lproj/Localizable.strings | 9 + DashWallet/tr.lproj/Localizable.strings | 9 + DashWallet/uk.lproj/Localizable.strings | 9 + DashWallet/vi.lproj/Localizable.strings | 9 + DashWallet/zh-Hans.lproj/Localizable.strings | 9 + .../zh-Hant-TW.lproj/Localizable.strings | 9 + DashWallet/zh.lproj/Localizable.strings | 9 + DashWallet/zh_TW.lproj/Localizable.strings | 9 + 53 files changed, 807 insertions(+), 413 deletions(-) delete mode 100644 DashWallet/Sources/Models/CrowdNode/Services/SendCoinsService.swift create mode 100644 DashWallet/Sources/Models/Transactions/SendCoinsService.swift create mode 100644 DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendConfirmationDialog.swift diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index 05fc917c7..064c09fa6 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -720,6 +720,8 @@ 75EE38D32CBE9EFC00845FFF /* MainMenuContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EE38D22CBE9EFC00845FFF /* MainMenuContentView.swift */; }; 75EE38D42CBE9EFC00845FFF /* MainMenuContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EE38D22CBE9EFC00845FFF /* MainMenuContentView.swift */; }; 75EE38D82CBFE52E00845FFF /* ContactsPlaceholderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EE38D72CBFE52B00845FFF /* ContactsPlaceholderViewController.swift */; }; + 75EE9F422DE2F750000AD1AD /* DashSpendConfirmationDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EE9F412DE2F74B000AD1AD /* DashSpendConfirmationDialog.swift */; }; + 75EE9F432DE2F750000AD1AD /* DashSpendConfirmationDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EE9F412DE2F74B000AD1AD /* DashSpendConfirmationDialog.swift */; }; 75F3F00D2C48F819004470EA /* RootEditProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759063EC2C42687F002F2AA9 /* RootEditProfileViewController.swift */; }; 75F51AAD2ABD8C800057B499 /* IntegrationViewController+Uphold.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F51AAC2ABD8C800057B499 /* IntegrationViewController+Uphold.swift */; }; 75F51AAF2ABD8D070057B499 /* IntegrationViewController+Coinbase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F51AAE2ABD8D070057B499 /* IntegrationViewController+Coinbase.swift */; }; @@ -2572,6 +2574,7 @@ 75EDC78DE1686E55AE12233C /* Pods-DashWalletScreenshotsUITests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DashWalletScreenshotsUITests.testnet.xcconfig"; path = "Pods/Target Support Files/Pods-DashWalletScreenshotsUITests/Pods-DashWalletScreenshotsUITests.testnet.xcconfig"; sourceTree = ""; }; 75EE38D22CBE9EFC00845FFF /* MainMenuContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuContentView.swift; sourceTree = ""; }; 75EE38D72CBFE52B00845FFF /* ContactsPlaceholderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsPlaceholderViewController.swift; sourceTree = ""; }; + 75EE9F412DE2F74B000AD1AD /* DashSpendConfirmationDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSpendConfirmationDialog.swift; sourceTree = ""; }; 75F2E0B61BE2D5F000EAE861 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; 75F51AAC2ABD8C800057B499 /* IntegrationViewController+Uphold.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IntegrationViewController+Uphold.swift"; sourceTree = ""; }; 75F51AAE2ABD8D070057B499 /* IntegrationViewController+Coinbase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IntegrationViewController+Coinbase.swift"; sourceTree = ""; }; @@ -3506,7 +3509,6 @@ 11E47BA928EB383E0097CFA0 /* Services */ = { isa = PBXGroup; children = ( - 11E47BAA28EB38510097CFA0 /* SendCoinsService.swift */, 117ED4A028EC86E0006E3EE4 /* TransactionObserver.swift */, 11517C86294B0FED004FC7BF /* CrowdNodeWebService.swift */, ); @@ -5107,6 +5109,7 @@ children = ( 47081195298CF1FE003FCA3D /* Model */, 472D13E2299E23B7006903F1 /* BalanceNotifier.swift */, + 11E47BAA28EB38510097CFA0 /* SendCoinsService.swift */, ); path = Transactions; sourceTree = ""; @@ -6067,6 +6070,7 @@ isa = PBXGroup; children = ( 753F75332DD0D41900D40DFE /* DashSpendPayScreen.swift */, + 75EE9F412DE2F74B000AD1AD /* DashSpendConfirmationDialog.swift */, 753F75362DD0D75F00D40DFE /* DashSpendPayViewModel.swift */, 75C3EDFD2DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift */, 75C3EDFE2DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift */, @@ -8617,6 +8621,7 @@ C9F42FAB29DC1098001BC549 /* ReceiveContentView.swift in Sources */, 47838B7528FFD1D10003E8AB /* AmountView.swift in Sources */, 4759D512292FD6F3002F20DC /* DWBasePayViewController.m in Sources */, + 75EE9F432DE2F750000AD1AD /* DashSpendConfirmationDialog.swift in Sources */, 1193FF3629602835004EA8D7 /* CrowdNodeTransferModel.swift in Sources */, 2A44312622CCC14F009BAF7F /* DWSetPinViewController.m in Sources */, 47F4B6C7294842DF00AED4C9 /* ConfirmOrderController.swift in Sources */, @@ -9636,6 +9641,7 @@ C943B3252A408CED00AF23C5 /* DWEditProfileViewController.m in Sources */, 75D6D8E52D96A6DB00E40A6D /* StubTransactionSource.swift in Sources */, C943B59C2A40EE5300AF23C5 /* DWNetworkErrorViewController.m in Sources */, + 75EE9F422DE2F750000AD1AD /* DashSpendConfirmationDialog.swift in Sources */, C9D2C8142A320AA000D15901 /* DWCenteredScrollView.m in Sources */, C9D2C8162A320AA000D15901 /* DWPhraseRepairViewController.m in Sources */, 75AA33CD2BF9C82700F12465 /* ModalDialog.swift in Sources */, diff --git a/DashWallet/Sources/Models/CrowdNode/Services/SendCoinsService.swift b/DashWallet/Sources/Models/CrowdNode/Services/SendCoinsService.swift deleted file mode 100644 index d0056f07d..000000000 --- a/DashWallet/Sources/Models/CrowdNode/Services/SendCoinsService.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by Andrei Ashikhmin -// Copyright © 2022 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Combine - -public final class SendCoinsService { - private let transactionManager: DSTransactionManager = DWEnvironment.sharedInstance().currentChainManager.transactionManager - - func sendCoins(address: String, amount: UInt64, - inputSelector: SingleInputAddressSelector? = nil, adjustAmountDownwards: Bool = false) async throws - -> DSTransaction { - let chain = DWEnvironment.sharedInstance().currentChain - let account = DWEnvironment.sharedInstance().currentAccount - let transaction = DSTransaction(on: chain) - - if inputSelector == nil { - // Forming transaction normally - let script = NSData.scriptPubKey(forAddress: address, for: chain) - account.update(transaction, forAmounts: [amount], toOutputScripts: [script], withFee: true) - } - else { - // Selecting proper inputs - let balance = inputSelector!.selectFor(tx: transaction) - transaction.addOutputAddress(address, amount: amount) - let feeAmount = chain.fee(forTxSize: UInt(transaction.size) + UInt(TX_OUTPUT_SIZE)) - - if amount + feeAmount > balance { - if adjustAmountDownwards { - let adjustedAmount = amount - feeAmount - let adjustedTx = try await sendCoins(address: address, amount: adjustedAmount, inputSelector: inputSelector) - return adjustedTx - } else { - throw Error.notEnoughFunds(selected: balance, amount: amount, fee: feeAmount) - } - } - - let change = balance - (amount + feeAmount) - - if change > 0 { - let changeAddress = inputSelector!.address - transaction.addOutputAddress(changeAddress, amount: change) - transaction.sortOutputsAccordingToBIP69() - } - } - - await account.sign(transaction) - account.register(transaction, saveImmediately: false) - try await transactionManager.publishTransaction(transaction) - - return transaction - } -} diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift index d47330755..141fe6be6 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift @@ -61,11 +61,6 @@ struct MerchantResponse: Codable { let cardImageUrl: String let currency: String - // Computed properties for backward compatibility - var website: String { - return "" // This field doesn't exist in the response - } - var minimumCardPurchase: Double { guard denominations.count >= 1, let min = Double(denominations[0]) else { return 0.0 } return min diff --git a/DashWallet/Sources/Models/Transactions/SendCoinsService.swift b/DashWallet/Sources/Models/Transactions/SendCoinsService.swift new file mode 100644 index 000000000..b978ae983 --- /dev/null +++ b/DashWallet/Sources/Models/Transactions/SendCoinsService.swift @@ -0,0 +1,180 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2022 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Combine + +public final class SendCoinsService: NSObject { + private let transactionManager: DSTransactionManager = DWEnvironment.sharedInstance().currentChainManager.transactionManager + + // Payment processing + private var paymentProcessor: DWPaymentProcessor? + private var pendingPaymentContinuation: CheckedContinuation? + + func sendCoins(address: String, amount: UInt64, + inputSelector: SingleInputAddressSelector? = nil, adjustAmountDownwards: Bool = false) async throws + -> DSTransaction { + let chain = DWEnvironment.sharedInstance().currentChain + let account = DWEnvironment.sharedInstance().currentAccount + let transaction = DSTransaction(on: chain) + + if inputSelector == nil { + // Forming transaction normally + let script = NSData.scriptPubKey(forAddress: address, for: chain) + account.update(transaction, forAmounts: [amount], toOutputScripts: [script], withFee: true) + } + else { + // Selecting proper inputs + let balance = inputSelector!.selectFor(tx: transaction) + transaction.addOutputAddress(address, amount: amount) + let feeAmount = chain.fee(forTxSize: UInt(transaction.size) + UInt(TX_OUTPUT_SIZE)) + + if amount + feeAmount > balance { + if adjustAmountDownwards { + let adjustedAmount = amount - feeAmount + let adjustedTx = try await sendCoins(address: address, amount: adjustedAmount, inputSelector: inputSelector) + return adjustedTx + } else { + throw Error.notEnoughFunds(selected: balance, amount: amount, fee: feeAmount) + } + } + + let change = balance - (amount + feeAmount) + + if change > 0 { + let changeAddress = inputSelector!.address + transaction.addOutputAddress(changeAddress, amount: change) + transaction.sortOutputsAccordingToBIP69() + } + } + + await account.sign(transaction) + account.register(transaction, saveImmediately: false) + try await transactionManager.publishTransaction(transaction) + + return transaction + } + + // MARK: - Gift Card Payment Processing + + func processGiftCardPayment(with paymentUrlString: String) async throws -> DSTransaction { + // Create payment input from the URL + guard let paymentUrl = URL(string: paymentUrlString) else { + throw CTXSpendError.paymentProcessingError("Invalid payment URL") + } + + // Use the existing payment infrastructure + let payModel = DWPayModel() + let paymentInput = payModel.paymentInput(with: paymentUrl) + + // If we have a BIP70 payment request URL, we need to fetch it first + guard paymentInput.request?.r != nil else { + throw CTXSpendError.paymentProcessingError("Invalid payment request") + } + + return try await fetchAndProcessPaymentRequest(paymentInput: paymentInput) + } + + private func fetchAndProcessPaymentRequest(paymentInput: DWPaymentInput) async throws -> DSTransaction { + return try await withCheckedThrowingContinuation { continuation in + self.pendingPaymentContinuation = continuation + + // Create and retain the processor + let processor = DWPaymentProcessor(delegate: self) + self.paymentProcessor = processor + + // Process the payment on the main actor to avoid Sendable issues + Task { @MainActor in + processor.processPaymentInput(paymentInput) + } + } + } + + private func completePayment(transaction: DSTransaction?, error: Swift.Error?) { + guard let continuation = pendingPaymentContinuation else { return } + + pendingPaymentContinuation = nil + + // Clean up the payment processor + paymentProcessor = nil + + if let error = error { + continuation.resume(throwing: error) + } else if let transaction = transaction { + continuation.resume(returning: transaction) + } else { + continuation.resume(throwing: CTXSpendError.paymentProcessingError("No transaction returned")) + } + } +} + +// MARK: - DWPaymentProcessorDelegate + +extension SendCoinsService: DWPaymentProcessorDelegate { + public func paymentProcessor(_ processor: DWPaymentProcessor, didSend protocolRequest: DSPaymentProtocolRequest, transaction: DSTransaction, contactItem: DWDPBasicUserItem?) { + completePayment(transaction: transaction, error: nil) + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, didFailWithError error: Swift.Error?, title: String?, message: String?) { + let fullError = NSError( + domain: "DashSpend", + code: -1, + userInfo: [ + NSLocalizedDescriptionKey: message ?? title ?? NSLocalizedString("Payment failed", comment: "") + ] + ) + completePayment(transaction: nil, error: error ?? fullError) + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, requestAmountWithDestination sendingDestination: String, details: DSPaymentProtocolDetails?, contactItem: DWDPBasicUserItem?) { + // Not needed for gift card payments + completePayment(transaction: nil, error: CTXSpendError.paymentProcessingError("Amount request not supported for gift cards")) + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, requestUserActionTitle title: String?, message: String?, actionTitle: String, cancel cancelBlock: (() -> Void)?, actionBlock: (() -> Void)?) { + // Auto-confirm for gift card purchases + actionBlock?() + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, confirmPaymentOutput paymentOutput: DWPaymentOutput) { + // Auto-confirm for gift card purchases + processor.confirmPaymentOutput(paymentOutput) + } + + public func paymentProcessorDidCancelTransactionSigning(_ processor: DWPaymentProcessor) { + completePayment(transaction: nil, error: NSError(domain: "DashSpend", code: -2, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Transaction cancelled", comment: "")])) + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, didSweepRequest protocolRequest: DSPaymentRequest, transaction: DSTransaction) { + completePayment(transaction: transaction, error: nil) + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, displayFileProcessResult result: String) { + // Not needed for gift card payments + } + + public func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { + // Not needed for gift card payments + } + + public func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { + // Progress is handled by the UI layer + } + + public func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { + // Progress is handled by the UI layer + } +} diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift index 4fafc0555..8d8be8f44 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift @@ -141,6 +141,7 @@ struct CTXSpendUserAuthScreen: View { showDecimalSeparator: false, actionButtonText: NSLocalizedString("Continue", comment: ""), actionEnabled: true, + inProgress: viewModel.isLoading, actionHandler: { viewModel.onContinue() } diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendConfirmationDialog.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendConfirmationDialog.swift new file mode 100644 index 000000000..24602da84 --- /dev/null +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendConfirmationDialog.swift @@ -0,0 +1,161 @@ +// +// 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 SwiftUI +import SDWebImageSwiftUI + +struct DashSpendConfirmationDialog: View { + let amount: String + let merchantName: String + let merchantIconUrl: String + let originalPrice: Decimal + let discount: Decimal + let onConfirm: () -> Void + let onCancel: () -> Void + + @Environment(\.presentationMode) private var presentationMode + + private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: kDefaultCurrencyCode) + + var body: some View { + VStack(spacing: 40) { + HStack { + Text(fiatFormatter.currencySymbol + amount) + .font(.system(size: 32, weight: .medium)) + .foregroundColor(.primaryText) + } + + // Details + VStack(spacing: 0) { + HStack(spacing: 8) { + Text(NSLocalizedString("From", comment: "DashSpend")) + .font(.body2) + .fontWeight(.medium) + .foregroundColor(.tertiaryText) + + Spacer() + + Image("image.explore.dash.wts.dash") + .resizable() + .frame(width: 24, height: 24) + + Text(NSLocalizedString("Dash Wallet", comment: "DashSpend")) + .font(.body2) + .foregroundColor(.primaryText) + } + .padding(.horizontal, 12) + .frame(height: 50) + + HStack(spacing: 8) { + Text(NSLocalizedString("To", comment: "DashSpend")) + .font(.body2) + .fontWeight(.medium) + .foregroundColor(.tertiaryText) + + Spacer() + + WebImage(url: URL(string: merchantIconUrl)) + .resizable() + .indicator(.activity) + .transition(.fade(duration: 0.3)) + .scaledToFit() + .frame(width: 24, height: 24) + .clipShape(Circle()) + + Text(merchantName) + .font(.body2) + .foregroundColor(.primaryText) + } + .padding(.horizontal, 12) + .frame(height: 50) + + HStack { + Text(NSLocalizedString("Gift card total", comment: "DashSpend")) + .font(.body2) + .fontWeight(.medium) + .foregroundColor(.tertiaryText) + + Spacer() + + Text(fiatFormatter.string(from: NSDecimalNumber(decimal: originalPrice)) ?? "") + .font(.body2) + .foregroundColor(.primaryText) + } + .padding(.horizontal, 12) + .frame(height: 50) + + HStack { + Text(NSLocalizedString("Discount", comment: "DashSpend")) + .font(.body2) + .fontWeight(.medium) + .foregroundColor(.tertiaryText) + + Spacer() + + Text("\(NSDecimalNumber(decimal: discount * 100).intValue)%") + .font(.body2) + .foregroundColor(.primaryText) + } + .padding(.horizontal, 12) + .frame(height: 50) + + HStack { + Text(NSLocalizedString("You pay", comment: "DashSpend")) + .font(.body2) + .fontWeight(.medium) + .foregroundColor(.tertiaryText) + + Spacer() + + Text(fiatFormatter.string(from: NSDecimalNumber(decimal: originalPrice * (1 - discount))) ?? "") + .font(.body2) + .foregroundColor(.primaryText) + } + .padding(.horizontal, 12) + .frame(height: 50) + } + .background(Color.white) + .cornerRadius(12) + .shadow(color: Color.shadow, radius: 10, x: 0, y: 5) + + HStack(spacing: 20) { + Button(action: onCancel) { + Text(NSLocalizedString("Cancel", comment: "DashSpend")) + .font(.system(size: 16, weight: .semibold)) + .foregroundColor(.primaryText) + .frame(maxWidth: .infinity) + .frame(height: 46) + } + .background(Color(UIColor.systemGray5)) + .cornerRadius(12) + + Button(action: onConfirm) { + Text(NSLocalizedString("Confirm", comment: "DashSpend")) + .font(.system(size: 16, weight: .semibold)) + .foregroundColor(.white) + } + .frame(maxWidth: .infinity) + .frame(height: 46) + .background(Color.dashBlue) + .cornerRadius(12) + } + } + .padding(.top, 15) + .padding(.horizontal, 20) + .edgesIgnoringSafeArea(.bottom) + } +} diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 8ef71f481..39936cc0f 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -17,7 +17,6 @@ import SwiftUI import SDWebImageSwiftUI -import Foundation struct DashSpendPayScreen: View { @Environment(\.presentationMode) private var presentationMode @@ -30,10 +29,6 @@ struct DashSpendPayScreen: View { @State private var errorMessage = "" @State private var errorTitle = "" - // Payment processor and delegate need to be retained for the duration of the payment - @State private var paymentProcessor: DWPaymentProcessor? - @State private var paymentDelegate: PaymentProcessorDelegate? - init(merchant: ExplorePointOfUse, justAuthenticated: Bool = false) { self.merchant = merchant self._viewModel = .init(wrappedValue: DashSpendPayViewModel(merchant: merchant)) @@ -128,6 +123,7 @@ struct DashSpendPayScreen: View { showDecimalSeparator: true, actionButtonText: NSLocalizedString("Preview", comment: ""), actionEnabled: viewModel.error == nil && !viewModel.showLimits && !viewModel.isLoading, + inProgress: viewModel.isProcessingPayment, actionHandler: { if !viewModel.isUserSignedIn() { showSignInError() @@ -191,16 +187,13 @@ struct DashSpendPayScreen: View { } .onDisappear { viewModel.unsubscribeFromAll() - // Clean up payment processor if still active - paymentProcessor = nil - paymentDelegate = nil } .sheet(isPresented: $showConfirmationDialog) { let dialog = BottomSheet( title: NSLocalizedString("Confirm", comment: "DashSpend"), showBackButton: Binding.constant(false) ) { - ConfirmationDialog( + DashSpendConfirmationDialog( amount: viewModel.input, merchantName: viewModel.merchantTitle, merchantIconUrl: viewModel.merchantIconUrl, @@ -227,116 +220,31 @@ struct DashSpendPayScreen: View { private func purchaseGiftCard() { Task { do { - // Show spinner/activity indicator could be added here - - let response = try await viewModel.purchaseGiftCard() - - // Success! Show success message and log to console - print("============ GIFT CARD PURCHASE SUCCESSFUL ============") - print("Merchant: \(response.merchantName)") - print("Amount: \(response.paymentFiatCurrency) \(response.paymentFiatAmount)") - print("Dash Amount: \(response.paymentCryptoAmount)") - print("Dash Payment URL: \(response.paymentUrls.first)") - + try await viewModel.purchaseGiftCardAndPay() - print("paymentId: \(response.paymentId)") - - print("Created At: \(response.created)") - print("Status: \(response.status)") - print("====================================================") - - // Process the payment using the payment URL - if let paymentUrlString = response.paymentUrls.first { - await processPayment(with: paymentUrlString.value, paymentId: response.paymentId) - } else { - throw CTXSpendError.paymentProcessingError("No payment URL received") + // Close the confirmation dialog and show success toast + showConfirmationDialog = false + showConfirmToast = true + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + showConfirmToast = false + presentationMode.wrappedValue.dismiss() } } catch let error as CTXSpendError { - errorTitle = NSLocalizedString("Purchase Failed", comment: "Alert title") + // Close the confirmation dialog and show error + showConfirmationDialog = false + errorTitle = NSLocalizedString("Purchase Failed", comment: "DashSpend") errorMessage = error.localizedDescription showErrorDialog = true - print("Gift card purchase failed with CTXSpendError: \(error)") + DSLogger.log("Gift card purchase failed with CTXSpendError: \(error)") } catch { - errorTitle = NSLocalizedString("Error", comment: "Alert title") + // Close the confirmation dialog and show error + showConfirmationDialog = false + errorTitle = NSLocalizedString("Error", comment: "") errorMessage = error.localizedDescription showErrorDialog = true - print("Gift card purchase failed with error: \(error)") - } - } - } - - private func processPayment(with paymentUrlString: String, paymentId: String) async { - do { - // Create payment input from the URL - guard let paymentUrl = URL(string: paymentUrlString) else { - throw CTXSpendError.paymentProcessingError("Invalid payment URL") - } - - // Use the existing payment infrastructure - let payModel = DWPayModel() - let paymentInput = payModel.paymentInput(with: paymentUrl) - - // If we have a BIP70 payment request URL, we need to fetch it first - if paymentInput.request?.r != nil { - try await fetchAndProcessPaymentRequest(paymentInput: paymentInput, paymentId: paymentId) - } else { - throw CTXSpendError.paymentProcessingError("Invalid payment request") - } - - } catch { - errorTitle = NSLocalizedString("Payment Error", comment: "Alert title") - errorMessage = error.localizedDescription - showErrorDialog = true - } - } - - private func fetchAndProcessPaymentRequest(paymentInput: DWPaymentInput, paymentId: String) async throws { - return try await withCheckedThrowingContinuation { continuation in - // Store the completion for later use - let completion: (DSTransaction?, Error?) -> Void = { transaction, error in - DispatchQueue.main.async { - if let error = error { - continuation.resume(throwing: error) - } else if let transaction = transaction { - // Payment successful - print("Payment transaction completed: \(transaction.txHashHexString)") - - // Save gift card information - self.viewModel.saveGiftCardDummy( - txHashData: transaction.txHashData, - giftCardId: paymentId - ) - - self.showConfirmToast = true - DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - self.showConfirmToast = false - self.presentationMode.wrappedValue.dismiss() - } - - continuation.resume() - } else { - continuation.resume(throwing: CTXSpendError.paymentProcessingError("No transaction returned")) - } - - // Clean up the payment processor and delegate after completion - self.paymentProcessor = nil - self.paymentDelegate = nil - } - } - - // Create and retain the delegate and processor - let delegate = PaymentProcessorDelegate(completion: completion) - let processor = DWPaymentProcessor(delegate: delegate) - - // Store them in instance variables to keep them alive - self.paymentDelegate = delegate - self.paymentProcessor = processor - - // Process the payment on the main thread - DispatchQueue.main.async { - processor.processPaymentInput(paymentInput) + DSLogger.log("Gift card purchase failed with error: \(error)") } } } @@ -347,208 +255,3 @@ struct DashSpendPayScreen: View { showErrorDialog = true } } - -struct ConfirmationDialog: View { - let amount: String - let merchantName: String - let merchantIconUrl: String - let originalPrice: Decimal - let discount: Decimal - let onConfirm: () -> Void - let onCancel: () -> Void - - @Environment(\.presentationMode) private var presentationMode - - private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: kDefaultCurrencyCode) - - var body: some View { - VStack(spacing: 40) { - HStack { - Text(fiatFormatter.currencySymbol + amount) - .font(.system(size: 32, weight: .medium)) - .foregroundColor(.primaryText) - } - - // Details - VStack(spacing: 0) { - HStack(spacing: 8) { - Text(NSLocalizedString("From", comment: "DashSpend")) - .font(.body2) - .fontWeight(.medium) - .foregroundColor(.tertiaryText) - - Spacer() - - Image("image.explore.dash.wts.dash") - .resizable() - .frame(width: 24, height: 24) - - Text(NSLocalizedString("Dash Wallet", comment: "DashSpend")) - .font(.body2) - .foregroundColor(.primaryText) - } - .padding(.horizontal, 12) - .frame(height: 50) - - HStack(spacing: 8) { - Text(NSLocalizedString("To", comment: "DashSpend")) - .font(.body2) - .fontWeight(.medium) - .foregroundColor(.tertiaryText) - - Spacer() - - WebImage(url: URL(string: merchantIconUrl)) - .resizable() - .indicator(.activity) - .transition(.fade(duration: 0.3)) - .scaledToFit() - .frame(width: 24, height: 24) - .clipShape(Circle()) - - Text(merchantName) - .font(.body2) - .foregroundColor(.primaryText) - } - .padding(.horizontal, 12) - .frame(height: 50) - - HStack { - Text(NSLocalizedString("Gift card total", comment: "DashSpend")) - .font(.body2) - .fontWeight(.medium) - .foregroundColor(.tertiaryText) - - Spacer() - - Text(fiatFormatter.string(from: NSDecimalNumber(decimal: originalPrice)) ?? "") - .font(.body2) - .foregroundColor(.primaryText) - } - .padding(.horizontal, 12) - .frame(height: 50) - - HStack { - Text(NSLocalizedString("Discount", comment: "DashSpend")) - .font(.body2) - .fontWeight(.medium) - .foregroundColor(.tertiaryText) - - Spacer() - - Text("\(NSDecimalNumber(decimal: discount * 100).intValue)%") - .font(.body2) - .foregroundColor(.primaryText) - } - .padding(.horizontal, 12) - .frame(height: 50) - - HStack { - Text(NSLocalizedString("You pay", comment: "DashSpend")) - .font(.body2) - .fontWeight(.medium) - .foregroundColor(.tertiaryText) - - Spacer() - - Text(fiatFormatter.string(from: NSDecimalNumber(decimal: originalPrice * (1 - discount))) ?? "") - .font(.body2) - .foregroundColor(.primaryText) - } - .padding(.horizontal, 12) - .frame(height: 50) - } - .background(Color.white) - .cornerRadius(12) - .shadow(color: Color.shadow, radius: 10, x: 0, y: 5) - - HStack(spacing: 20) { - Button(action: onCancel) { - Text(NSLocalizedString("Cancel", comment: "DashSpend")) - .font(.system(size: 16, weight: .semibold)) - .foregroundColor(.primaryText) - .frame(maxWidth: .infinity) - .frame(height: 46) - } - .background(Color(UIColor.systemGray5)) - .cornerRadius(12) - - Button(action: onConfirm) { - Text(NSLocalizedString("Confirm", comment: "DashSpend")) - .font(.system(size: 16, weight: .semibold)) - .foregroundColor(.white) - .frame(maxWidth: .infinity) - .frame(height: 46) - } - .background(Color.dashBlue) - .cornerRadius(12) - } - } - .padding(.top, 15) - .padding(.horizontal, 20) - .edgesIgnoringSafeArea(.bottom) - } -} - -// MARK: - PaymentProcessorDelegate - -class PaymentProcessorDelegate: NSObject, DWPaymentProcessorDelegate { - private let completion: (DSTransaction?, Error?) -> Void - - init(completion: @escaping (DSTransaction?, Error?) -> Void) { - self.completion = completion - } - - func paymentProcessor(_ processor: DWPaymentProcessor, didSend protocolRequest: DSPaymentProtocolRequest, transaction: DSTransaction, contactItem: DWDPBasicUserItem?) { - completion(transaction, nil) - } - - func paymentProcessor(_ processor: DWPaymentProcessor, didFailWithError error: Error?, title: String?, message: String?) { - let fullError = NSError( - domain: "DashSpend", - code: -1, - userInfo: [ - NSLocalizedDescriptionKey: message ?? title ?? NSLocalizedString("Payment failed", comment: "") - ] - ) - completion(nil, error ?? fullError) - } - - func paymentProcessor(_ processor: DWPaymentProcessor, requestAmountWithDestination sendingDestination: String, details: DSPaymentProtocolDetails?, contactItem: DWDPBasicUserItem?) { - // Not needed for our use case - } - - func paymentProcessor(_ processor: DWPaymentProcessor, requestUserActionTitle title: String?, message: String?, actionTitle: String, cancel cancelBlock: (() -> Void)?, actionBlock: (() -> Void)?) { - // Auto-confirm for gift card purchases - actionBlock?() - } - - func paymentProcessor(_ processor: DWPaymentProcessor, confirmPaymentOutput paymentOutput: DWPaymentOutput) { - // Auto-confirm for gift card purchases - processor.confirmPaymentOutput(paymentOutput) - } - - func paymentProcessorDidCancelTransactionSigning(_ processor: DWPaymentProcessor) { - completion(nil, NSError(domain: "DashSpend", code: -2, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Transaction cancelled", comment: "")])) - } - - func paymentProcessor(_ processor: DWPaymentProcessor, didSweepRequest protocolRequest: DSPaymentRequest, transaction: DSTransaction) { - completion(transaction, nil) - } - - func paymentProcessor(_ processor: DWPaymentProcessor, displayFileProcessResult result: String) { - // Not needed for our use case - } - - func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { - // Not needed for our use case - } - - func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { - // Could show progress indicator here if needed - } - - func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { - // Could hide progress indicator here if needed - } -} diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 62f5c3719..5355e8fb1 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -21,14 +21,16 @@ import Combine private let defaultCurrency = kDefaultCurrencyCode @MainActor -class DashSpendPayViewModel: ObservableObject { +class DashSpendPayViewModel: NSObject, ObservableObject { private var cancellableBag = Set() private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: defaultCurrency) private let ctxSpendService = CTXSpendService.shared + private let sendCoinsService = SendCoinsService() private(set) var amount: Decimal = 0 private(set) var savingsFraction: Decimal = 0.0 @Published private(set) var isLoading = false + @Published private(set) var isProcessingPayment = false let currencySymbol: String = { let locale = Locale.current as NSLocale @@ -158,46 +160,65 @@ class DashSpendPayViewModel: ObservableObject { let merchantInfo = try await ctxSpendService.getMerchant(merchantId: merchantId) // Update merchant details - savingsFraction = Decimal(merchantInfo.savingsPercentage) / 100 + savingsFraction = Decimal(merchantInfo.savingsPercentage) / Decimal(10000) if merchantInfo.denominationType == .Range { minimumAmount = Decimal(merchantInfo.minimumCardPurchase) maximumAmount = Decimal(merchantInfo.maximumCardPurchase) } - // Revalidate current amount checkAmountForErrors() } catch { DSLogger.log("Failed to get merchant info: \(error)") } } - func purchaseGiftCard() async throws -> GiftCardResponse { + func purchaseGiftCardAndPay() async throws { + isProcessingPayment = true + defer { isProcessingPayment = false } + + let response = try await purchaseGiftCardAPI() + + // Success! Log the response + DSLogger.log("============ GIFT CARD PURCHASE SUCCESSFUL ============") + DSLogger.log("Merchant: \(response.merchantName)") + DSLogger.log("Amount: \(response.paymentFiatCurrency) \(response.paymentFiatAmount)") + DSLogger.log("Dash Amount: \(response.paymentCryptoAmount)") + DSLogger.log("Dash Payment URL: \(response.paymentUrls.first?.value ?? "none")") + DSLogger.log("Payment ID: \(response.paymentId)") + DSLogger.log("Created At: \(response.created)") + DSLogger.log("Status: \(response.status)") + DSLogger.log("====================================================") + + // Process the payment using the payment URL + guard let paymentUrlString = response.paymentUrls.first?.value else { + throw CTXSpendError.paymentProcessingError("No payment URL received") + } + + let transaction = try await sendCoinsService.processGiftCardPayment(with: paymentUrlString) + + // Payment successful - save gift card information + DSLogger.log("Payment transaction completed: \(transaction.txHashHexString)") + saveGiftCardDummy(txHashData: transaction.txHashData, giftCardId: response.paymentId) + } + + private func purchaseGiftCardAPI() async throws -> GiftCardResponse { guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { DSLogger.log("Purchase gift card failed: User not signed in or merchant ID is empty") throw CTXSpendError.unauthorized } DSLogger.log("Attempting to purchase gift card for merchant \(merchantId) with amount \(amount)") - isLoading = true - defer { isLoading = false } - do { - let fiatAmountString = String(format: "%.2f", Double(truncating: amount as NSDecimalNumber)) - DSLogger.log("Making API request to purchase gift card: merchantId=\(merchantId), amount=\(fiatAmountString)USD") - - let response = try await ctxSpendService.purchaseGiftCard( - merchantId: merchantId, - fiatAmount: fiatAmountString, - fiatCurrency: "USD", - cryptoCurrency: "DASH" - ) - - return response - } catch { - DSLogger.log("Gift card purchase failed with error: \(error)") - throw error - } + let fiatAmountString = String(format: "%.2f", Double(truncating: amount as NSDecimalNumber)) + DSLogger.log("Making API request to purchase gift card: merchantId=\(merchantId), amount=\(fiatAmountString)USD") + + return try await ctxSpendService.purchaseGiftCard( + merchantId: merchantId, + fiatAmount: fiatAmountString, + fiatCurrency: "USD", + cryptoCurrency: "DASH" + ) } func isUserSignedIn() -> Bool { @@ -205,11 +226,8 @@ class DashSpendPayViewModel: ObservableObject { } func saveGiftCardDummy(txHashData: Data, giftCardId: String) { - // TODO: Implement gift card storage in iOS - // For now, just log the information DSLogger.log("Gift card saved - txId: \(txHashData.hexEncodedString()), giftCardId: \(giftCardId)") - // In a full implementation, this would save to Core Data or UserDefaults - // Similar to how the Android version saves to a Room database + // TODO: save dummy to SQLite } } diff --git a/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift b/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift index 9c066dc55..8e8d6f4fa 100644 --- a/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift +++ b/DashWallet/Sources/UI/Payment Controller/Enter Amount/ProvideAmountViewController.swift @@ -93,7 +93,11 @@ final class ProvideAmountViewController: SendAmountViewController { destination: destination, balanceLabel: balanceLabel, model: self.model as! SendAmountModel, - avatarView: { UIViewWrapper(uiView: avatarView ?? EmptyUIView()) } + avatarView: { + if let avatarView = avatarView { + UIViewWrapper(uiView: avatarView) + } + } ) let swiftUIController = UIHostingController(rootView: intro) swiftUIController.view.backgroundColor = UIColor.dw_secondaryBackground() diff --git a/DashWallet/Sources/UI/SwiftUI Components/NumericKeyboardView.swift b/DashWallet/Sources/UI/SwiftUI Components/NumericKeyboardView.swift index 12611ae25..a46e3df03 100644 --- a/DashWallet/Sources/UI/SwiftUI Components/NumericKeyboardView.swift +++ b/DashWallet/Sources/UI/SwiftUI Components/NumericKeyboardView.swift @@ -5,6 +5,7 @@ struct NumericKeyboardView: View { let showDecimalSeparator: Bool let actionButtonText: String let actionEnabled: Bool + let inProgress: Bool let actionHandler: () -> Void private var rows: [[String]] { @@ -43,13 +44,16 @@ struct NumericKeyboardView: View { .foregroundColor(.primaryText) } } + .disabled(inProgress) } } + .opacity(inProgress ? 0.5 : 1.0) } DashButton( text: actionButtonText, isEnabled: !value.isEmpty && actionEnabled, + isLoading: inProgress, action: actionHandler ) .padding(.top, 20) @@ -78,6 +82,7 @@ struct NumericKeyboardView: View { showDecimalSeparator: true, actionButtonText: NSLocalizedString("Verify", comment: "Button title for numeric keyboard action"), actionEnabled: true, + inProgress: false, actionHandler: { print("Action button tapped") } ).frame(height: 400) } diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index d930e5987..29077bf8f 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "طريقة الدفع "; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "إلمس لمعرفة الحد"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "تاريخ المعاملات"; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index 979731597..ffc0bccaf 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID лимит"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index e1b1b557f..dc2071ca3 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index 59e646437..0a9d25859 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Placení..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index aaaf2bb00..0745fa455 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index ff194201c..3a5a92656 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Bezahle..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Zahlungsmethode"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Zahlungsart"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch-ID Limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaktionshistorie"; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 3958be7e6..5ed5549cb 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Πληρωμή..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Μέθοδος πληρωμής"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Τύπος πληρωμής"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Όριο Touch ID "; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Ιστορικό συναλλαγών"; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index fe25ea82f..97b9084b3 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index bc25bf424..9ea416694 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index 1cbd7f5ab..e9c5c15f2 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Pagando..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Método de pago"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Tipo de pago"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Límite de Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Historial de transacciones"; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index 860b283c0..37741980d 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index 0cd988e95..0c36bd09c 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "روش پرداخت"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "سابقه تراکنش‌ها"; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index 797cfd1d2..ddc75eff3 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index c2c874c1f..22e185238 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Nagbabayad..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Paraan ng Pagbayad"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Uri ng Pagbabayad"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Kasaysayan ng Transaksyon"; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index 118a7eb8c..629ed5257 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paiement en cours..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Méthode de paiement"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Type de paiement"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Limite pour TouchID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Historique des transactions"; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index 6871221c6..714580f9d 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index 0f1a8e4c3..a537874a7 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID összeghatár"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 46182352e..483201c81 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Membayar..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Metode pembayaran"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Tipe Pembayaran"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "ID sentuhan terbatas"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Riwayat Transaksi"; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index e6d4da20f..c6f135a3f 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Pagamento in corso..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Metodo di pagamento"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Tipo di Pagamento"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Limite \"Touch ID\""; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Cronologia delle transazioni"; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index 2b443f139..7cad9ab84 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "支払い中…"; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "支払い方法"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "支払い方法"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch IDの送金可能額"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "取引履歴"; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index 91251d91f..18dc2ebb6 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "지불 중..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "지불 방법"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "지불 유형"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "터치 ID 제한"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "거래 내역"; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index 8842f6320..b80b75334 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index b886b71ad..a5267d711 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index 47be8fba7..2090da32d 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index db6ed0b05..b3c7265fc 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Aan het betalen..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Betalingsmethode"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Betalingswijze"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "touch ID limiet"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transactiegeschiedenis"; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index a7250c467..05dfc1384 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Płacę..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Metoda płatności"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Typ płatności"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Historia Transakcji"; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index ba0f1ec34..fae66c6b7 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Pagando..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Método de pagamento"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Tipo de Pagamento"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Limite de ID de toque"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Histórico de Transações"; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index c82060905..da8a2edae 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "limita pentru Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index b3cb4bcfe..23222dbeb 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Оплата..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Способ оплаты"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Способ оплаты"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Лимит Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "История транзакций"; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 4324d8ea4..31fcc3e0d 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Platí sa..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Spôsob platby"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Typ platby"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Limit pre Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "História transakcií"; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index 5acc72609..34e1d8bb7 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index e5366eef7..df4d8021e 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index 557abfe87..2be99b146 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 78937522a..3922526f9 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Limit za Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index f9ac86744..0b0d7012e 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limit"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index e5540e2ad..2de954ba4 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "กำลังชำระเงิน"; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "วิธีการชำระเงิน"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "ประเภทการชำระเงิน"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "ขีดจำกัด Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "ประวัติการทำรายการ"; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 9b08c5f89..8614fceb6 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Ödeniyor..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Ödeme şekli"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Ödeme türü"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID limiti"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "İşlem Geçmişi"; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index 14990bab0..c7d9ecda2 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Оплата..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Спосіб оплати"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Типа платежу"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Touch ID ліміт"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Історія Транзакцій"; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index 2d0e104b3..e28207930 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Đang gửi..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "Giới hạn Touch ID"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index 50a73f025..799879b67 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "触控ID限制"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index f16b553bb..e5ca370e6 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "Paying..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "Payment method"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "Payment Type"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "指紋辨識解鎖的限制"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "Transaction History"; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index 01725e959..e6701182f 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "付款中..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "付款方式"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "付款类型"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "触控ID限制"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "交易记录"; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index 9b32b42c6..b0e9ada6a 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -1751,9 +1751,15 @@ /* 4 out of 4 in the Paying Animation */ "Paying..." = "付款中..."; +/* No comment provided by engineer. */ +"Payment failed" = "Payment failed"; + /* Coinbase/Buy Dash */ "Payment method" = "付款方式"; +/* CTXSpend error */ +"Payment processing error: %@" = "Payment processing error: %@"; + /* Explore Dash/Merchants/Filters */ "Payment Type" = "支付方式"; @@ -2494,6 +2500,9 @@ /* No comment provided by engineer. */ "Touch ID limit" = "指紋辨識解鎖的限制"; +/* No comment provided by engineer. */ +"Transaction cancelled" = "Transaction cancelled"; + /* CrowdNode */ "Transaction History" = "交易記錄"; From 2db4113ea3359bd90318642d9eb6a26ae39b06e4 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Mon, 26 May 2025 14:32:02 +0700 Subject: [PATCH 06/10] fix: ios 15.5 navigation --- .../Details/PointOfUseDetailsViewController.swift | 12 ++++-------- .../Views/DashSpend/CTXSpendTermsScreen.swift | 3 +++ .../Views/DashSpend/CTXSpendUserAuthScreen.swift | 6 +++++- 3 files changed, 12 insertions(+), 9 deletions(-) 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 3d6bb686b..63bdaf43c 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift @@ -195,11 +195,9 @@ extension PointOfUseDetailsViewController { private func showCTXSpendAuth(authType: CTXSpendUserAuthType) { let hostingController = UIHostingController( - rootView: NavigationView { - CTXSpendUserAuthScreen(authType: authType) { - self.navigationController?.popViewController(animated: false) - self.showDashSpendPayScreen(justAuthenticated: true) - } + rootView: CTXSpendUserAuthScreen(authType: authType) { + self.navigationController?.popViewController(animated: false) + self.showDashSpendPayScreen(justAuthenticated: true) } ) @@ -208,9 +206,7 @@ extension PointOfUseDetailsViewController { private func showDashSpendPayScreen(justAuthenticated: Bool = false) { let hostingController = UIHostingController( - rootView: NavigationView { - DashSpendPayScreen(merchant: self.pointOfUse, justAuthenticated: justAuthenticated) - } + rootView: DashSpendPayScreen(merchant: self.pointOfUse, justAuthenticated: justAuthenticated) ) self.navigationController?.pushViewController(hostingController, animated: true) diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift index 5ad38f4ed..571e37294 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift @@ -111,6 +111,9 @@ struct CTXSpendTermsScreen: View { .padding(20) } } + .navigationBarHidden(true) + .navigationBarBackButtonHidden(true) + .edgesIgnoringSafeArea(.top) NavigationLink( destination: CTXSpendUserAuthScreen( diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift index 8d8be8f44..4bcae2226 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift @@ -146,7 +146,7 @@ struct CTXSpendUserAuthScreen: View { viewModel.onContinue() } ).frame(maxWidth: .infinity) - .frame(height: 320) + .frame(height: UIDevice.isIphone5OrLess ? 290 : 320) .padding(.horizontal, 20) .padding(.bottom, 20) } else { @@ -182,6 +182,10 @@ struct CTXSpendUserAuthScreen: View { } } .background(Color.secondaryBackground) + .ignoresSafeArea(.keyboard, edges: .bottom) + .navigationBarHidden(true) + .navigationBarBackButtonHidden(true) + .edgesIgnoringSafeArea(.top) .onAppear { viewModel.setup(screenType: authType) From 319f19c5302a699b891c28df2a659fe6369e2ba6 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Tue, 27 May 2025 13:33:24 +0700 Subject: [PATCH 07/10] feat: implement refreshing token --- DashWallet.xcodeproj/project.pbxproj | 6 ++ .../Model/Entites/CTXSpendModels.swift | 9 ++ .../Explore Dash/Services/CTXSpendAPI.swift | 53 +++++++++--- .../Services/CTXSpendEndpoint.swift | 8 +- .../Services/CTXSpendService.swift | 25 +++++- .../Services/CTXSpendTokenService.swift | 82 +++++++++++++++++++ .../PointOfUseDetailsViewController.swift | 40 ++++++--- .../Views/DashSpend/DashSpendPayScreen.swift | 2 +- .../DashSpend/DashSpendPayViewModel.swift | 5 +- DashWallet/ar.lproj/Localizable.strings | 6 ++ DashWallet/bg.lproj/Localizable.strings | 6 ++ DashWallet/ca.lproj/Localizable.strings | 6 ++ DashWallet/cs.lproj/Localizable.strings | 6 ++ DashWallet/da.lproj/Localizable.strings | 6 ++ DashWallet/de.lproj/Localizable.strings | 6 ++ DashWallet/el.lproj/Localizable.strings | 6 ++ DashWallet/en.lproj/Localizable.strings | 6 ++ DashWallet/eo.lproj/Localizable.strings | 6 ++ DashWallet/es.lproj/Localizable.strings | 6 ++ DashWallet/et.lproj/Localizable.strings | 6 ++ DashWallet/fa.lproj/Localizable.strings | 6 ++ DashWallet/fi.lproj/Localizable.strings | 6 ++ DashWallet/fil.lproj/Localizable.strings | 6 ++ DashWallet/fr.lproj/Localizable.strings | 6 ++ DashWallet/hr.lproj/Localizable.strings | 6 ++ DashWallet/hu.lproj/Localizable.strings | 6 ++ DashWallet/id.lproj/Localizable.strings | 6 ++ DashWallet/it.lproj/Localizable.strings | 6 ++ DashWallet/ja.lproj/Localizable.strings | 6 ++ DashWallet/ko.lproj/Localizable.strings | 6 ++ DashWallet/mk.lproj/Localizable.strings | 6 ++ DashWallet/ms.lproj/Localizable.strings | 6 ++ DashWallet/nb.lproj/Localizable.strings | 6 ++ DashWallet/nl.lproj/Localizable.strings | 6 ++ DashWallet/pl.lproj/Localizable.strings | 6 ++ DashWallet/pt.lproj/Localizable.strings | 6 ++ DashWallet/ro.lproj/Localizable.strings | 6 ++ DashWallet/ru.lproj/Localizable.strings | 6 ++ DashWallet/sk.lproj/Localizable.strings | 6 ++ DashWallet/sl.lproj/Localizable.strings | 6 ++ DashWallet/sl_SI.lproj/Localizable.strings | 6 ++ DashWallet/sq.lproj/Localizable.strings | 6 ++ DashWallet/sr.lproj/Localizable.strings | 6 ++ DashWallet/sv.lproj/Localizable.strings | 6 ++ DashWallet/th.lproj/Localizable.strings | 6 ++ DashWallet/tr.lproj/Localizable.strings | 6 ++ DashWallet/uk.lproj/Localizable.strings | 6 ++ DashWallet/vi.lproj/Localizable.strings | 6 ++ DashWallet/zh-Hans.lproj/Localizable.strings | 6 ++ .../zh-Hant-TW.lproj/Localizable.strings | 6 ++ DashWallet/zh.lproj/Localizable.strings | 6 ++ DashWallet/zh_TW.lproj/Localizable.strings | 6 ++ 52 files changed, 459 insertions(+), 29 deletions(-) create mode 100644 DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index 064c09fa6..cc48c1504 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -656,6 +656,8 @@ 759C8FA02B593589004B1305 /* CrowdNodeAPYView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759C8F9E2B593589004B1305 /* CrowdNodeAPYView.swift */; }; 75A0A3F32CA7DBCF003ED48B /* TimeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A0A3F22CA7DBCF003ED48B /* TimeUtils.swift */; }; 75A0A3F42CA7DBCF003ED48B /* TimeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A0A3F22CA7DBCF003ED48B /* TimeUtils.swift */; }; + 75A2F3032DE48C860046BE17 /* CTXSpendTokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2F3022DE48C860046BE17 /* CTXSpendTokenService.swift */; }; + 75A2F3042DE48C860046BE17 /* CTXSpendTokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2F3022DE48C860046BE17 /* CTXSpendTokenService.swift */; }; 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 */; }; @@ -2524,6 +2526,7 @@ 759AFDE22CC67E89007072D2 /* VotingInfoScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingInfoScreen.swift; sourceTree = ""; }; 759C8F9E2B593589004B1305 /* CrowdNodeAPYView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeAPYView.swift; sourceTree = ""; }; 75A0A3F22CA7DBCF003ED48B /* TimeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeUtils.swift; sourceTree = ""; }; + 75A2F3022DE48C860046BE17 /* CTXSpendTokenService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendTokenService.swift; sourceTree = ""; }; 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 = ""; }; @@ -5649,6 +5652,7 @@ 47AE8B9828BFAD0000490F5E /* Services */ = { isa = PBXGroup; children = ( + 75A2F3022DE48C860046BE17 /* CTXSpendTokenService.swift */, 754565C42DAA52A000DA4E8E /* CTXSpendAPI.swift */, 754565C52DAA52A000DA4E8E /* CTXSpendEndpoint.swift */, 754565C72DAA52A000DA4E8E /* CTXSpendService.swift */, @@ -8527,6 +8531,7 @@ 47C661AD28F972BD00028A8D /* NumberKeyboardButton.swift in Sources */, 11AE3DD82997C599000856EE /* IsDefaultEmail.swift in Sources */, 2A9FFF2A2233E60F00956D5F /* DWUpholdAccountObject.m in Sources */, + 75A2F3042DE48C860046BE17 /* CTXSpendTokenService.swift in Sources */, 2A9FFE812230FF4700956D5F /* DWFormTableViewController.m in Sources */, C909614D29EFF7D600002D82 /* WalletKeysOverviewModel.swift in Sources */, 4751137528DAF28800223B77 /* UIAssembly.swift in Sources */, @@ -9240,6 +9245,7 @@ C943B31D2A408CED00AF23C5 /* DWUserProfileContainerView.m in Sources */, C9D2C6F02A320AA000D15901 /* UIImage+Utils.m in Sources */, C943B4BE2A40A54600AF23C5 /* DWGlobalMatchFailedHeaderView.m in Sources */, + 75A2F3032DE48C860046BE17 /* CTXSpendTokenService.swift in Sources */, C943B4C22A40A54600AF23C5 /* BaseCollectionReusableView.m in Sources */, C9D2C6F22A320AA000D15901 /* DWSetupViewController.m in Sources */, C9D2C6F32A320AA000D15901 /* ExploreDatabaseConnection.swift in Sources */, diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift index 141fe6be6..ea4b47c9c 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift @@ -11,6 +11,10 @@ struct VerifyEmailRequest: Codable { let code: String } +public struct RefreshTokenRequest: Codable { + let refreshToken: String +} + public struct PurchaseGiftCardRequest: Codable { let cryptoCurrency: String let fiatCurrency: String @@ -25,6 +29,11 @@ struct VerifyEmailResponse: Codable { let refreshToken: String } +struct RefreshTokenResponse: Codable { + let accessToken: String + let refreshToken: String +} + struct GiftCardResponse: Codable { let id: String let percentDiscount: String diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift index e594f6616..0e18b9a03 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift @@ -23,6 +23,7 @@ enum CTXSpendError: Error, LocalizedError { case parsingError case invalidCode case unauthorized + case tokenRefreshFailed case insufficientFunds case invalidMerchant case invalidAmount @@ -32,29 +33,32 @@ enum CTXSpendError: Error, LocalizedError { public var errorDescription: String? { switch self { case .networkError: - return NSLocalizedString("Network error. Please check your connection and try again.", comment: "CTXSpend error") + return NSLocalizedString("Network error. Please check your connection and try again.", comment: "DashSpend") case .parsingError: - return NSLocalizedString("Error processing server response. Please try again later.", comment: "CTXSpend error") + return NSLocalizedString("Error processing server response. Please try again later.", comment: "DashSpend") case .invalidCode: return NSLocalizedString("Invalid verification code. Please try again.", comment: "CTXSpend error") case .unauthorized: - return NSLocalizedString("Please sign in to your DashSpend account.", comment: "CTXSpend error") + return NSLocalizedString("Please sign in to your DashSpend account.", comment: "DashSpend") + case .tokenRefreshFailed: + return NSLocalizedString("Your session expired", comment: "DashSpend") case .insufficientFunds: - return NSLocalizedString("Insufficient funds to complete this purchase.", comment: "CTXSpend error") + return NSLocalizedString("Insufficient funds to complete this purchase.", comment: "DashSpend") case .invalidMerchant: - return NSLocalizedString("This merchant is currently unavailable.", comment: "CTXSpend error") + return NSLocalizedString("This merchant is currently unavailable.", comment: "DashSpend") case .invalidAmount: - return NSLocalizedString("Invalid amount. Please check merchant limits.", comment: "CTXSpend error") + return NSLocalizedString("Invalid amount. Please check merchant limits.", comment: "DashSpend") case .unknown: - return NSLocalizedString("An unknown error occurred. Please try again later.", comment: "CTXSpend error") + return NSLocalizedString("An unknown error occurred. Please try again later.", comment: "DashSpend") case .paymentProcessingError(let details): - return String(format: NSLocalizedString("Payment processing error: %@", comment: "CTXSpend error"), details) + return String(format: NSLocalizedString("Payment processing error: %@", comment: "DashSpend"), details) } } } protocol CTXSpendAPIAccessTokenProvider: AnyObject { var accessToken: String? { get } + var refreshToken: String? { get } } final class CTXSpendAPI: HTTPClient { @@ -65,7 +69,8 @@ final class CTXSpendAPI: HTTPClient { try checkAccessTokenIfNeeded(for: target) try await super.request(target) } catch HTTPClientError.statusCode(let r) where r.statusCode == 401 { - throw CTXSpendError.unauthorized + try await handleUnauthorizedError(for: target) + try await super.request(target) } } @@ -74,7 +79,8 @@ final class CTXSpendAPI: HTTPClient { try checkAccessTokenIfNeeded(for: target) return try await super.request(target) } catch HTTPClientError.statusCode(let r) where r.statusCode == 401 { - throw CTXSpendError.unauthorized + try await handleUnauthorizedError(for: target) + return try await super.request(target) } catch HTTPClientError.statusCode(let r) where r.statusCode == 400 { if target.path.contains("/api/verify") { throw CTXSpendError.invalidCode @@ -85,6 +91,28 @@ final class CTXSpendAPI: HTTPClient { } } + // Direct request method that bypasses refresh logic (used by token service) + func requestDirectly(_ target: CTXSpendEndpoint) async throws -> R where R: Decodable { + return try await super.request(target) + } + + func requestDirectly(_ target: CTXSpendEndpoint) async throws { + try await super.request(target) + } + + private func handleUnauthorizedError(for target: CTXSpendEndpoint) async throws { + guard target.authorizationType == .bearer else { + throw CTXSpendError.unauthorized + } + + try await CTXSpendTokenService.shared.refreshAccessToken() + + // Update the access token provider after refresh + accessTokenProvider = { [weak self] in + self?.ctxSpendAPIAccessTokenProvider?.accessToken + } + } + private func checkAccessTokenIfNeeded(for target: CTXSpendEndpoint) throws { guard target.authorizationType == .bearer else { return @@ -106,5 +134,10 @@ final class CTXSpendAPI: HTTPClient { ctxSpendAPIAccessTokenProvider!.accessToken } self.ctxSpendAPIAccessTokenProvider = ctxSpendAPIAccessTokenProvider + + // Configure the token service + if let tokenProvider = ctxSpendAPIAccessTokenProvider as? CTXSpendTokenProvider { + CTXSpendTokenService.shared.configure(with: tokenProvider) + } } } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift index 3d309fff0..060ed3977 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift @@ -40,6 +40,7 @@ struct CTXSpendAPIError: Decodable { public enum CTXSpendEndpoint { case login(email: String) case verifyEmail(email: String, code: String) + case refreshToken(RefreshTokenRequest) case purchaseGiftCard(PurchaseGiftCardRequest) case getMerchant(String) case getGiftCard(String) @@ -50,7 +51,7 @@ public enum CTXSpendEndpoint { extension CTXSpendEndpoint: TargetType, AccessTokenAuthorizable { public var authorizationType: Moya.AuthorizationType? { switch self { - case .login, .verifyEmail: + case .login, .verifyEmail, .refreshToken: return nil default: return .bearer @@ -65,6 +66,7 @@ extension CTXSpendEndpoint: TargetType, AccessTokenAuthorizable { switch self { case .login: return "login" case .verifyEmail: return "verify-email" + case .refreshToken: return "refresh-token" case .purchaseGiftCard: return "gift-cards" case .getMerchant(let merchantId): return "merchants/\(merchantId)" case .getGiftCard(let txid): return "gift-cards" @@ -73,7 +75,7 @@ extension CTXSpendEndpoint: TargetType, AccessTokenAuthorizable { public var method: Moya.Method { switch self { - case .login, .verifyEmail, .purchaseGiftCard: + case .login, .verifyEmail, .refreshToken, .purchaseGiftCard: return .post default: return .get @@ -88,6 +90,8 @@ extension CTXSpendEndpoint: TargetType, AccessTokenAuthorizable { case .verifyEmail(let email, let code): let verifyRequest = VerifyEmailRequest(email: email, code: code) return .requestJSONEncodable(verifyRequest) + case .refreshToken(let request): + return .requestJSONEncodable(request) case .purchaseGiftCard(let request): return .requestJSONEncodable(request) default: diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift index 53e40c0c0..38682caab 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift @@ -18,7 +18,7 @@ import Foundation import Combine -class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { +class CTXSpendService: CTXSpendAPIAccessTokenProvider, CTXSpendTokenProvider, ObservableObject { public static let shared: CTXSpendService = .init() private let userDefaults = UserDefaults.standard @@ -33,6 +33,10 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { return KeychainService.load(key: Keys.accessToken) } + var refreshToken: String? { + return KeychainService.load(key: Keys.refreshToken) + } + var userEmail: String? { KeychainService.load(key: Keys.email) } @@ -91,6 +95,24 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { updateSignInState() } + // MARK: - Token Management + + func updateTokens(accessToken: String, refreshToken: String) { + KeychainService.save(key: Keys.accessToken, data: accessToken) + KeychainService.save(key: Keys.refreshToken, data: refreshToken) + updateSignInState() + } + + func clearTokensOnRefreshFailure() { + KeychainService.delete(key: Keys.accessToken) + KeychainService.delete(key: Keys.refreshToken) + updateSignInState() + } + + func refreshToken() async throws { + try await CTXSpendTokenService.shared.refreshAccessToken() + } + // MARK: - Gift Card Methods func purchaseGiftCard(merchantId: String, fiatAmount: String, fiatCurrency: String = "USD", cryptoCurrency: String = "DASH") async throws -> GiftCardResponse { @@ -151,7 +173,6 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, ObservableObject { func getMerchant(merchantId: String) async throws -> MerchantResponse { do { let response: MerchantResponse = try await CTXSpendAPI.shared.request(.getMerchant(merchantId)) - DSLogger.log("Successfully retrieved merchant info: \(merchantId)") return response } catch let error as CTXSpendError { DSLogger.log("Failed to get merchant with CTXSpendError: \(error)") diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift new file mode 100644 index 000000000..0879127ca --- /dev/null +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift @@ -0,0 +1,82 @@ +// +// 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 + +// Forward declaration to avoid circular imports +protocol CTXSpendTokenProvider: AnyObject { + var accessToken: String? { get } + var refreshToken: String? { get } + func updateTokens(accessToken: String, refreshToken: String) + func clearTokensOnRefreshFailure() +} + +// MARK: - CTXSpendTokenService + +class CTXSpendTokenService { + static let shared = CTXSpendTokenService() + + private var tokenRefreshTask: Task? + private weak var tokenProvider: CTXSpendTokenProvider? + + private init() {} + + func configure(with tokenProvider: CTXSpendTokenProvider) { + self.tokenProvider = tokenProvider + } + + func refreshAccessToken() async throws { + // If there's already a refresh task running, wait for it + if let task = tokenRefreshTask { + try await task.value + return + } + + guard let tokenProvider = tokenProvider, + let refreshToken = tokenProvider.refreshToken, + !refreshToken.isEmpty else { + return + } + + tokenRefreshTask = Task { + defer { + tokenRefreshTask = nil + } + + DSLogger.log("CTXSpend: Attempting to refresh access token") + + do { + let request = RefreshTokenRequest(refreshToken: refreshToken) + let response: RefreshTokenResponse = try await CTXSpendAPI.shared.requestDirectly(.refreshToken(request)) + + // Update tokens through the service + tokenProvider.updateTokens(accessToken: response.accessToken, refreshToken: response.refreshToken) + + DSLogger.log("CTXSpend: Token refresh successful") + } catch { + DSLogger.log("CTXSpend: Token refresh failed: \(error)") + + // Clear tokens on refresh failure + tokenProvider.clearTokensOnRefreshFailure() + + throw CTXSpendError.tokenRefreshFailed + } + } + + try await tokenRefreshTask!.value + } +} 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 63bdaf43c..0f9132360 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift @@ -54,6 +54,7 @@ class PointOfUseDetailsViewController: UIViewController { super.viewDidLoad() title = pointOfUse.name configureHierarchy() + tryRefreshCtxToken() } } @@ -160,7 +161,25 @@ extension PointOfUseDetailsViewController { prepareContentView() showDetailsView() } - +} + +extension PointOfUseDetailsViewController { + func detailsView(for pointOfUse: ExplorePointOfUse) -> PointOfUseDetailsView? { + switch pointOfUse.category { + case .merchant: + return PointOfUseDetailsView(merchant: pointOfUse, isShowAllHidden: isShowAllHidden) + case .atm: + return AtmDetailsView(merchant: pointOfUse, isShowAllHidden: isShowAllHidden) + case .unknown: + return nil + } + } +} + + +// Mark: DashSpend + +extension PointOfUseDetailsViewController { private func showCTXSpendLoginInfo() { let swiftUIView = CTXSpendLoginInfoView( onCreateNewAccount: { [weak self] in @@ -211,17 +230,14 @@ extension PointOfUseDetailsViewController { self.navigationController?.pushViewController(hostingController, animated: true) } -} - -extension PointOfUseDetailsViewController { - func detailsView(for pointOfUse: ExplorePointOfUse) -> PointOfUseDetailsView? { - switch pointOfUse.category { - case .merchant: - return PointOfUseDetailsView(merchant: pointOfUse, isShowAllHidden: isShowAllHidden) - case .atm: - return AtmDetailsView(merchant: pointOfUse, isShowAllHidden: isShowAllHidden) - case .unknown: - return nil + + private func tryRefreshCtxToken() { + Task { + do { + try await CTXSpendService.shared.refreshToken() + } catch CTXSpendError.tokenRefreshFailed { + await showModalDialog(style: .warning, icon: .system("exclamationmark.triangle.fill"), heading: NSLocalizedString("Your session expired", comment: "DashSpend"), textBlock1: NSLocalizedString("It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash.", comment: "DashSpend"), positiveButtonText: NSLocalizedString("Dismiss", comment: "")) + } } } } diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 39936cc0f..6babc2a0b 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -122,7 +122,7 @@ struct DashSpendPayScreen: View { value: $viewModel.input, showDecimalSeparator: true, actionButtonText: NSLocalizedString("Preview", comment: ""), - actionEnabled: viewModel.error == nil && !viewModel.showLimits && !viewModel.isLoading, + actionEnabled: viewModel.error == nil && !viewModel.showLimits && !viewModel.isLoading && viewModel.hasValidLimits, inProgress: viewModel.isProcessingPayment, actionHandler: { if !viewModel.isUserSignedIn() { diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 5355e8fb1..78e7171f1 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -80,8 +80,9 @@ class DashSpendPayViewModel: NSObject, ObservableObject { NSLocalizedString("You are buying a %@ gift card for %@ (%d%% discount)", comment: "DashSpend"), originalPrice, formattedDiscountedPrice, discount) } - var showCost: Bool { error == nil && amount >= minimumAmount && amount <= maximumAmount } - var showLimits: Bool { error == nil && !showCost } + var showCost: Bool { error == nil && amount >= minimumAmount && amount <= maximumAmount && hasValidLimits } + var showLimits: Bool { error == nil && !showCost && hasValidLimits } + var hasValidLimits: Bool { minimumAmount > 0 || maximumAmount > 0 } var minimumLimitMessage: String { String.localizedStringWithFormat(NSLocalizedString("Min: %@", comment: "DashSpend"), fiatFormatter.string(for: minimumAmount) ?? "0.0" ) } var maximumLimitMessage: String { String.localizedStringWithFormat(NSLocalizedString("Max: %@", comment: "DashSpend"), fiatFormatter.string(for: maximumAmount) ?? "0.0" ) } var isMixing: Bool { CoinJoinService.shared.mixingState.isInProgress } diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index 29077bf8f..8457b8a94 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index ffc0bccaf..b31155c52 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Вашата транзакция беше изпратена и сумата би трябвало да се появи във вашият портфейл до няколко минути."; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index dc2071ca3..63b47de44 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index 0a9d25859..2eb8032fc 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Transakce byla odeslána a částka by se měla objevit v pěněžence během pár minut."; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index 0745fa455..181989ac4 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index 3a5a92656..fc64816d0 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Es wäre selbst für erfahrene Nutzer sehr schwer, deine Transaktionshistorie zu bestimmen."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Deine Anfrage wurde abgebrochen."; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Deine Transaktion wurde versendet und der Betrag sollte in ein paar Minuten in der Wallet zu sehen sein."; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 5ed5549cb..8bb047209 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Θα ήταν πολύ δύσκολο για προχωρημένους χρήστες με οποιοδήποτε επίπεδο τεχνική εξειδίκευση να προσδιορίσουν το ιστορικό συναλλαγών σας."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Το αίτημά σας ακυρώθηκε"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Η συναλλαγή σας απεστάλη και το ποσό θα πρέπει να εμφανιστεί στο πορτοφόλι σας σε λίγα λεπτά."; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index 97b9084b3..fe811b941 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index 9ea416694..22daf04e3 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index e9c5c15f2..bf8d64987 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Sería muy difícil para usuarios avanzados con cualquier nivel de experiencia técnica determinar tu historial de transacciones."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Tu solicitud fue cancelada"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Tu transacción se envió y la cantidad debería aparecer en tu billetera en unos minutos."; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index 37741980d..6dbe4b6d9 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index 0c36bd09c..2ee0587f6 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index ddc75eff3..e7a7ed27d 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index 22e185238..84dc64fd8 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Napakahirap para sa mga advanced na user na may anumang antas ng teknikal na kadalubhasaan na matukoy ang iyong kasaysayan ng transaksyon"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Kinansela ang iyong kahilingan"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Ang iyong transaksyon ay naipadala at ang halaga ay dapat makita sa iyong pitaka sa loob ng ilang minuto."; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index 629ed5257..50d0c7ffc 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Il serait très difficile, pour des utilisateurs avancés avec quelque niveau d'expertise technique, de déterminer votre historique de transaction"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Votre demande a été annulée"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Votre transaction a été envoyée et le montant devrait apparaître dans votre portefeuille sous quelques minutes."; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index 714580f9d..84fab9396 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index a537874a7..f5ab65b5b 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 483201c81..7b9856577 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Akan sangat sulit bagi pengguna tingkat lanjut dengan tingkat keahlian teknis apa pun untuk menentukan riwayat transaksi Anda"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Permintaan anda telah dibatalkan"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Transaksi Anda telah dikirim dan jumlahnya akan muncul di dompet Anda dalam beberapa menit."; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index c6f135a3f..6aa7e05a3 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Sarebbe molto difficile per gli utenti avanzati con qualsiasi livello di competenza tecnica determinare la cronologia delle transazioni"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "La tua richiesta è stata annullata"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "La tua transazione è stata inviata e l'importo dovrebbe essere visualizzato nel tuo portafoglio entro pochi minuti."; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index 7cad9ab84..af6bd2300 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "技術的な専門知識を持つ上級ユーザーにとっても、取引履歴を確認することは非常に困難です"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "申請がキャンセルされました"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "あなたの取引は送られたので、数分内にその金額がウォレットに表示されるでしょう"; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index 18dc2ebb6..2f670683b 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "어떤 수준의 기술적 전문 지식을 가진 고급 사용자라고 하더라도 자신의 거래 기록을 결정하는 것은 어려울 수 있습니다."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "당신의 요청이 취소되었습니다"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "당신의 거래가 완료되었으며 수 분 이내에 당신의 지갑에 잔액이 표시될 예정입니다."; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index b80b75334..5a32d3155 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index a5267d711..ce0ddd9dd 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index 2090da32d..8f511db7a 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index b3c7265fc..4a24a659a 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Het zou voor gevorderde gebruikers met welke technische expertise dan ook erg moeilijk zijn om je transactiegeschiedenis te achterhalen"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Je aanvraag is geannuleerd"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "De transactie is verzonden en het bedrag verschijnt binnen een paar minuten in je de portemonnee."; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index 05dfc1384..666e59efe 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Nawet użytkownicy o bardzo zaawansowanej wiedzy technicznej nie będą mogli ustalić definitywnej historię transakcji."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Twoja prośba została anulowana"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Twoja transakcja została wysłana a ilość powinna pojawić się na Twoim koncie w kilka minut."; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index fae66c6b7..1f907268d 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Seria muito difícil para usuários avançados com qualquer nível de conhecimento técnico determinar seu histórico de transações"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Sua solicitação foi cancelada"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Sua transação foi enviada e o valor aparecerá na sua carteira em alguns minutos. "; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index da8a2edae..346bad03f 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Tranzacția ta a fost trimisă, iar suma trebuie să apară în portofel în câteva minute."; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index 23222dbeb..38890be96 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Продвинутым пользователям с любым уровнем знаний в области технологий будет довольно сложно определить вашу историю транзакций"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Ваш запрос был отклонён"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Ваша транзакция была отправлена и её сумма отобразится в вашем кошельке через несколько минут."; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 31fcc3e0d..916a9c572 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Pre pokročilých používateľov s vysokou úrovňou technických znalostí by bolo veľmi ťažké určiť vašu históriu transakcií"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Vaša žiadosť bola zrušená"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Vaša transakcia bola odoslaná a čiastka by sa mala objaviť vo vašej peňaženke v priebehu niekoľkých minút."; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index 34e1d8bb7..dfdecc84c 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index df4d8021e..33864a364 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index 2be99b146..df818ac3e 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 3922526f9..175ceac2f 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index 0b0d7012e..bb5615804 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index 2de954ba4..92a38cb7b 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "เป็นเรื่องยากมากสำหรับผู้ใช้ระดับสูงที่มีความเชี่ยวชาญทางเทคนิคทุกระดับในการพิจารณาประวัติการทำธุรกรรมของคุณ"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "ธุรกรรมของคุณถูกส่งแล้วและจำนวนเงินจะปรากฏใน wallet ของคุณในอีกไม่กี่นาที"; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 8614fceb6..72b5f39fe 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Herhangi bir düzeyde teknik uzmanlığa sahip ileri düzey kullanıcıların işlem geçmişinizi belirlemesi çok zor olacaktır."; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "İsteğiniz iptal edildi"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "İşleminiz yapıldı ve birkaç dakika içinde tutar cüzdanınızda görülecek."; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index c7d9ecda2..fc20abca3 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "Досвідченим користувачам із будь-яким рівнем технічних знань буде дуже важко визначити вашу історію транзакцій"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Ваш запит скасовано"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Ваша транзакція була відправлена ​​і її сума відобразиться у вашому гаманці за кілька хвилин."; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index e28207930..7f185ed30 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Giao dịch của bạn đã được gửi và số tiền sẽ xuất hiện trong ví của bạn trong vài phút."; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index 799879b67..71fec48ca 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index e5ca370e6..3b1a8b03e 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "Your request was cancelled"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "Your transaction was sent and the amount should appear in your wallet in a few minutes."; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index e6701182f..18013987b 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "具有任何水平技术专长的进阶用户都很难决定您的交易历史记录"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "您的申请已被取消"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "您的交易已被发送, 金额将几分钟内出现在您的钱包."; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index b0e9ada6a..c9a063ade 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* CoinJoin */ "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees" = "It is recommended to be on a Wi-Fi network to avoid incurring additional mixing fees"; +/* DashSpend */ +"It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash." = "It looks like you haven’t used DashSpend in a while. For security reasons, you’ve been logged out.\n\nPlease sign in again to continue exploring where to spend your Dash."; + /* Coinbase */ "It would be very difficult for advanced users with any level of technical expertise to determine your transaction history" = "即使對於具有任何技術專業水平的高級用戶來說,要確定您的交易歷史記錄都是非常困難的"; @@ -3064,6 +3067,9 @@ /* Usernames */ "Your request was cancelled" = "您的申请已取消"; +/* DashSpend */ +"Your session expired" = "Your session expired"; + /* No comment provided by engineer. */ "Your transaction was sent and the amount should appear in your wallet in a few minutes." = "您的交易已發送,金額應在幾分鐘內顯示在您的錢包中。"; From 0fbf4faf07316eb49af0c22bc4f9c3f5b6617059 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Tue, 27 May 2025 13:47:11 +0700 Subject: [PATCH 08/10] chore: simplify savingsBasisPoints calculations --- .../Explore Dash/Model/Entites/ExplorePointOfUse.swift | 8 ++++++++ .../Details/Views/PointOfUseDetailsView.swift | 2 +- .../Merchants & ATMs/List/Cells/MerchantItemCell.swift | 2 +- .../Views/DashSpend/DashSpendPayViewModel.swift | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift index 3d3ab5512..78c33223c 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift @@ -58,6 +58,14 @@ extension ExplorePointOfUse { let type: `Type` let deeplink: String? let savingsBasisPoints: Int // in basis points 1 = 0.001% + + func toSavingPercentages() -> Double { + return Double(savingsBasisPoints) / 100 + } + + func toSavingsFraction() -> Double { + return Double(savingsBasisPoints) / 10000 + } } var merchant: Merchant? { 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 e38a11bdf..a374d313c 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 @@ -334,7 +334,7 @@ extension PointOfUseDetailsView { let savingsTag = SavingsTagView() savingsTag.backgroundColor = .clear savingsTag.translatesAutoresizingMaskIntoConstraints = false - savingsTag.setText(String(format: NSLocalizedString("Save %.2f%%", comment: "DashSpend"), Double(m.savingsBasisPoints) / 100)) + savingsTag.setText(String(format: NSLocalizedString("Save %.2f%%", comment: "DashSpend"), m.toSavingPercentages())) containerView.addSubview(savingsTag) NSLayoutConstraint.activate([ diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Cells/MerchantItemCell.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Cells/MerchantItemCell.swift index e4beb53c8..c62c1294f 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Cells/MerchantItemCell.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Cells/MerchantItemCell.swift @@ -47,7 +47,7 @@ class MerchantItemCell: PointOfUseItemCell { if merchant.savingsBasisPoints > 0 { savingsLabel.isHidden = false - savingsLabel.text = String(format: NSLocalizedString("~%.0f%%", comment: "Savings percentage"), Double(merchant.savingsBasisPoints) / 100) + savingsLabel.text = String(format: NSLocalizedString("~%.0f%%", comment: "Savings percentage"), merchant.toSavingPercentages()) } else { savingsLabel.isHidden = true } diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 78e7171f1..364285c62 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -90,7 +90,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject { init(merchant: ExplorePointOfUse) { merchantTitle = merchant.name merchantIconUrl = merchant.logoLocation ?? "" - savingsFraction = Decimal(merchant.merchant?.savingsBasisPoints ?? 0) / Decimal(10000) + savingsFraction = Decimal(merchant.merchant?.toSavingsFraction() ?? 0.0) if let merchantId = merchant.merchant?.merchantId { self.merchantId = merchantId From ceeef7ed3f0751fc46175de6b6c93ef591cbf893 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Tue, 27 May 2025 17:02:31 +0700 Subject: [PATCH 09/10] feat: limit errors and support email --- DashWallet.xcodeproj/project.pbxproj | 32 +++--- .../Explore Dash/Model/CTXConstants.swift | 1 + .../Explore Dash/Services/CTXSpendAPI.swift | 3 + .../Services/CTXSpendEndpoint.swift | 5 + .../Services/CTXSpendService.swift | 34 ++++--- .../Services/CTXSpendTokenService.swift | 1 - .../Models/Uphold/DWUpholdMainnetConstants.m | 1 + .../Views/DashSpend/DashSpendPayScreen.swift | 32 +++++- .../DashSpend/DashSpendPayViewModel.swift | 99 ++++++++++++------- DashWallet/ar.lproj/Localizable.strings | 6 ++ DashWallet/bg.lproj/Localizable.strings | 6 ++ DashWallet/ca.lproj/Localizable.strings | 6 ++ DashWallet/cs.lproj/Localizable.strings | 6 ++ DashWallet/da.lproj/Localizable.strings | 6 ++ DashWallet/de.lproj/Localizable.strings | 6 ++ DashWallet/el.lproj/Localizable.strings | 6 ++ DashWallet/en.lproj/Localizable.strings | 6 ++ DashWallet/eo.lproj/Localizable.strings | 6 ++ DashWallet/es.lproj/Localizable.strings | 6 ++ DashWallet/et.lproj/Localizable.strings | 6 ++ DashWallet/fa.lproj/Localizable.strings | 6 ++ DashWallet/fi.lproj/Localizable.strings | 6 ++ DashWallet/fil.lproj/Localizable.strings | 6 ++ DashWallet/fr.lproj/Localizable.strings | 6 ++ DashWallet/hr.lproj/Localizable.strings | 6 ++ DashWallet/hu.lproj/Localizable.strings | 6 ++ DashWallet/id.lproj/Localizable.strings | 6 ++ DashWallet/it.lproj/Localizable.strings | 6 ++ DashWallet/ja.lproj/Localizable.strings | 6 ++ DashWallet/ko.lproj/Localizable.strings | 6 ++ DashWallet/mk.lproj/Localizable.strings | 6 ++ DashWallet/ms.lproj/Localizable.strings | 6 ++ DashWallet/nb.lproj/Localizable.strings | 6 ++ DashWallet/nl.lproj/Localizable.strings | 6 ++ DashWallet/pl.lproj/Localizable.strings | 6 ++ DashWallet/pt.lproj/Localizable.strings | 6 ++ DashWallet/ro.lproj/Localizable.strings | 6 ++ DashWallet/ru.lproj/Localizable.strings | 6 ++ DashWallet/sk.lproj/Localizable.strings | 6 ++ DashWallet/sl.lproj/Localizable.strings | 6 ++ DashWallet/sl_SI.lproj/Localizable.strings | 6 ++ DashWallet/sq.lproj/Localizable.strings | 6 ++ DashWallet/sr.lproj/Localizable.strings | 6 ++ DashWallet/sv.lproj/Localizable.strings | 6 ++ DashWallet/th.lproj/Localizable.strings | 6 ++ DashWallet/tr.lproj/Localizable.strings | 6 ++ DashWallet/uk.lproj/Localizable.strings | 6 ++ DashWallet/vi.lproj/Localizable.strings | 6 ++ DashWallet/zh-Hans.lproj/Localizable.strings | 6 ++ .../zh-Hant-TW.lproj/Localizable.strings | 6 ++ DashWallet/zh.lproj/Localizable.strings | 6 ++ DashWallet/zh_TW.lproj/Localizable.strings | 6 ++ 52 files changed, 396 insertions(+), 70 deletions(-) diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index cc48c1504..bc674a480 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -10361,7 +10361,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -10501,7 +10501,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -10675,7 +10675,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -10697,7 +10697,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -10722,7 +10722,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -10749,7 +10749,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -10781,7 +10781,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -10810,7 +10810,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -11489,7 +11489,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -11602,7 +11602,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -11658,7 +11658,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -11683,7 +11683,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -11800,7 +11800,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -11912,7 +11912,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -11967,7 +11967,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -11992,7 +11992,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.5.0; + MARKETING_VERSION = 8.4.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; diff --git a/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift b/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift index 24eaa0d90..98363b9ae 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift @@ -18,4 +18,5 @@ class CTXConstants { static let baseURI = "https://spend.ctx.com/" static let ctxGiftCardAgreementUrl = "https://ctx.com/gift-card-agreement/" + static let supportEmail = "support@ctx.com" } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift index 0e18b9a03..23e11f9e3 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendAPI.swift @@ -27,6 +27,7 @@ enum CTXSpendError: Error, LocalizedError { case insufficientFunds case invalidMerchant case invalidAmount + case customError(String) case unknown case paymentProcessingError(String) @@ -48,6 +49,8 @@ enum CTXSpendError: Error, LocalizedError { return NSLocalizedString("This merchant is currently unavailable.", comment: "DashSpend") case .invalidAmount: return NSLocalizedString("Invalid amount. Please check merchant limits.", comment: "DashSpend") + case .customError(let message): + return message case .unknown: return NSLocalizedString("An unknown error occurred. Please try again later.", comment: "DashSpend") case .paymentProcessingError(let details): diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift index 060ed3977..71558f5f8 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendEndpoint.swift @@ -32,7 +32,12 @@ struct CTXSpendAPIError: Decodable { } } + struct FieldError: Decodable { + let fiatAmount: [String]? + } + var errors: [Error] + let fields: FieldError? } // MARK: - CTXSpendEndpoint diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift index 38682caab..9884ea034 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendService.swift @@ -136,21 +136,29 @@ class CTXSpendService: CTXSpendAPIAccessTokenProvider, CTXSpendTokenProvider, Ob if case .statusCode(let response) = error { switch response.statusCode { case 400: - if let errorData = try? JSONDecoder().decode(CTXSpendAPIError.self, from: response.data), - let firstError = errorData.errors.first { - // Look for specific error messages - let errorMessage = firstError.message.lowercased() - - if errorMessage.contains("insufficient") || errorMessage.contains("funds") { - throw CTXSpendError.insufficientFunds - } else if errorMessage.contains("merchant") { - throw CTXSpendError.invalidMerchant - } else if errorMessage.contains("amount") || errorMessage.contains("value") { - throw CTXSpendError.invalidAmount + if let errorData = try? JSONDecoder().decode(CTXSpendAPIError.self, from: response.data) { + // Check for limit error first + if let fiatAmountErrors = errorData.fields?.fiatAmount, + let firstFiatError = fiatAmountErrors.first, + (firstFiatError == "above threshold" || firstFiatError == "below threshold") { + throw CTXSpendError.customError(NSLocalizedString("The purchase limits for this merchant have changed. Please contact CTX Support for more information.", comment: "DashSpend")) } - // Custom error with the actual message from API - throw NSError(domain: "CTXSpend", code: 400, userInfo: [NSLocalizedDescriptionKey: firstError.message]) + if let firstError = errorData.errors.first { + // Look for specific error messages + let errorMessage = firstError.message.lowercased() + + if errorMessage.contains("insufficient") || errorMessage.contains("funds") { + throw CTXSpendError.insufficientFunds + } else if errorMessage.contains("merchant") { + throw CTXSpendError.invalidMerchant + } else if errorMessage.contains("amount") || errorMessage.contains("value") { + throw CTXSpendError.invalidAmount + } + + // Custom error with the actual message from API + throw NSError(domain: "CTXSpend", code: 400, userInfo: [NSLocalizedDescriptionKey: firstError.message]) + } } case 401, 403: throw CTXSpendError.unauthorized diff --git a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift index 0879127ca..3733a50ae 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/CTXSpendTokenService.swift @@ -17,7 +17,6 @@ import Foundation -// Forward declaration to avoid circular imports protocol CTXSpendTokenProvider: AnyObject { var accessToken: String? { get } var refreshToken: String? { get } 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/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 6babc2a0b..8b1e259ac 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -26,6 +26,7 @@ struct DashSpendPayScreen: View { @State var showConfirmToast: Bool @State private var showConfirmationDialog = false @State private var showErrorDialog = false + @State private var showCustomErrorDialog = false @State private var errorMessage = "" @State private var errorTitle = "" @@ -113,6 +114,7 @@ struct DashSpendPayScreen: View { } .frame(maxWidth: .infinity) + .frame(height: 20) .padding(.top, 20) .padding(.bottom, 10) @@ -173,6 +175,27 @@ struct DashSpendPayScreen: View { .background(Color.black.opacity(0.7)) .edgesIgnoringSafeArea(.all) } + + if showCustomErrorDialog { + ModalDialog( + style: .error, + icon: .system("exclamationmark.triangle.fill"), + heading: errorTitle, + textBlock1: errorMessage, + positiveButtonText: NSLocalizedString("Close", comment: ""), + positiveButtonAction: { + showCustomErrorDialog = false + }, + negativeButtonText: NSLocalizedString("Contact CTX Support", comment: "DashSpend"), + negativeButtonAction: { + showCustomErrorDialog = false + viewModel.contactCTXSupport() + } + ) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.black.opacity(0.7)) + .edgesIgnoringSafeArea(.all) + } } .ignoresSafeArea(.all, edges: .bottom) .background(Color.primaryBackground) @@ -230,15 +253,18 @@ struct DashSpendPayScreen: View { presentationMode.wrappedValue.dismiss() } } catch let error as CTXSpendError { - // Close the confirmation dialog and show error showConfirmationDialog = false errorTitle = NSLocalizedString("Purchase Failed", comment: "DashSpend") errorMessage = error.localizedDescription - showErrorDialog = true + + if case .customError = error { + showCustomErrorDialog = true + } else { + showErrorDialog = true + } DSLogger.log("Gift card purchase failed with CTXSpendError: \(error)") } catch { - // Close the confirmation dialog and show error showConfirmationDialog = false errorTitle = NSLocalizedString("Error", comment: "") errorMessage = error.localizedDescription diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 364285c62..3b3681a98 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -26,7 +26,8 @@ class DashSpendPayViewModel: NSObject, ObservableObject { private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: defaultCurrency) private let ctxSpendService = CTXSpendService.shared private let sendCoinsService = SendCoinsService() - + + private var merchantId: String = "" private(set) var amount: Decimal = 0 private(set) var savingsFraction: Decimal = 0.0 @Published private(set) var isLoading = false @@ -68,8 +69,6 @@ class DashSpendPayViewModel: NSObject, ObservableObject { } } - private var merchantId: String = "" - var costMessage: String { let originalPrice = fiatFormatter.string(for: amount) ?? "0.00" let discountedPrice = amount * (1 - savingsFraction) @@ -119,6 +118,65 @@ class DashSpendPayViewModel: NSObject, ObservableObject { } } + func purchaseGiftCardAndPay() async throws { + isProcessingPayment = true + defer { isProcessingPayment = false } + + let response = try await purchaseGiftCardAPI() + + // Success! Log the response + DSLogger.log("============ GIFT CARD PURCHASE SUCCESSFUL ============") + DSLogger.log("Merchant: \(response.merchantName)") + DSLogger.log("Amount: \(response.paymentFiatCurrency) \(response.paymentFiatAmount)") + DSLogger.log("Dash Amount: \(response.paymentCryptoAmount)") + DSLogger.log("Dash Payment URL: \(response.paymentUrls.first?.value ?? "none")") + DSLogger.log("Payment ID: \(response.paymentId)") + DSLogger.log("Created At: \(response.created)") + DSLogger.log("Status: \(response.status)") + DSLogger.log("====================================================") + + // Process the payment using the payment URL + guard let paymentUrlString = response.paymentUrls.first?.value else { + throw CTXSpendError.paymentProcessingError("No payment URL received") + } + + let transaction = try await sendCoinsService.processGiftCardPayment(with: paymentUrlString) + + // Payment successful - save gift card information + DSLogger.log("Payment transaction completed: \(transaction.txHashHexString)") + saveGiftCardDummy(txHashData: transaction.txHashData, giftCardId: response.paymentId) + } + + func isUserSignedIn() -> Bool { + return ctxSpendService.isUserSignedIn + } + + func contactCTXSupport() { + let subject = "CTX Issue: Spending Limit Problem" + + var body = "Merchant details\n" + body += "name: \(merchantTitle)\n" + body += "id: \(merchantId)\n" + body += "min: \(minimumAmount)\n" + body += "max: \(maximumAmount)\n" + body += "discount: \(savingsFraction)\n" +// body += "denominations type: \(denominationsType)\n" TODO: fixed denoms +// body += "denominations: \(denominations)\n" + body += "\n" + + body += "Purchase Details\n" + body += "amount: \(input)\n" + body += "\n" + + // Add device information + 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) ?? "")") { + UIApplication.shared.open(emailURL) + } + } + func unsubscribeFromAll() { cancellableBag.removeAll() } @@ -174,35 +232,6 @@ class DashSpendPayViewModel: NSObject, ObservableObject { } } - func purchaseGiftCardAndPay() async throws { - isProcessingPayment = true - defer { isProcessingPayment = false } - - let response = try await purchaseGiftCardAPI() - - // Success! Log the response - DSLogger.log("============ GIFT CARD PURCHASE SUCCESSFUL ============") - DSLogger.log("Merchant: \(response.merchantName)") - DSLogger.log("Amount: \(response.paymentFiatCurrency) \(response.paymentFiatAmount)") - DSLogger.log("Dash Amount: \(response.paymentCryptoAmount)") - DSLogger.log("Dash Payment URL: \(response.paymentUrls.first?.value ?? "none")") - DSLogger.log("Payment ID: \(response.paymentId)") - DSLogger.log("Created At: \(response.created)") - DSLogger.log("Status: \(response.status)") - DSLogger.log("====================================================") - - // Process the payment using the payment URL - guard let paymentUrlString = response.paymentUrls.first?.value else { - throw CTXSpendError.paymentProcessingError("No payment URL received") - } - - let transaction = try await sendCoinsService.processGiftCardPayment(with: paymentUrlString) - - // Payment successful - save gift card information - DSLogger.log("Payment transaction completed: \(transaction.txHashHexString)") - saveGiftCardDummy(txHashData: transaction.txHashData, giftCardId: response.paymentId) - } - private func purchaseGiftCardAPI() async throws -> GiftCardResponse { guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { DSLogger.log("Purchase gift card failed: User not signed in or merchant ID is empty") @@ -222,11 +251,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject { ) } - func isUserSignedIn() -> Bool { - return ctxSpendService.isUserSignedIn - } - - func saveGiftCardDummy(txHashData: Data, giftCardId: String) { + private func saveGiftCardDummy(txHashData: Data, giftCardId: String) { DSLogger.log("Gift card saved - txId: \(txHashData.hexEncodedString()), giftCardId: \(giftCardId)") // TODO: save dummy to SQLite diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index 8457b8a94..db510869d 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "اتصل بدعم كوين بيس"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index b31155c52..a0f787df5 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index 63b47de44..c5916ec9f 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index 2eb8032fc..313fc1cd1 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Čeká na přidání mezi kontakty"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index 181989ac4..2176c0fd4 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index fc64816d0..d7e44f15e 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Coinbase Support kontaktieren"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Kontaktanfrage ausstehend"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Der Mindestbetrag für eine Transaktion ist %@."; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 8bb047209..13780f36e 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Επικοινωνία με την υποστήριξη της Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Εκκρεμεί Αίτημα Επαφής"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Το ελάχιστο ποσό που μπορείτε να στείλετε είναι %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index fe811b941..b7bd2c83d 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index 22daf04e3..edecabce2 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index bf8d64987..575abf717 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Ponte en contacto con el soporte de Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Solicitud de contacto pendiente"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "El monto mínimo que puedes enviar es %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index 6dbe4b6d9..9b0062777 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index 2ee0587f6..89ce47526 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "با پشتیبانی کوین‌بیس تماس بگیرید"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index e7a7ed27d..2d240378b 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index 84dc64fd8..cb3c15fd2 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Makipag-ugnayan sa Suporta sa Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Nakabinbin ang Kahilingan sa Pakikipag-ugnay"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Ang pinakamababang halaga na maaari mong ipadala ay %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index 50d0c7ffc..0d873bd96 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contacter le service de soutien Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Demande de contact en attente"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Le montant minimal que vous pouvez envoyer est %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index 84fab9396..ca454e252 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index f5ab65b5b..d9b386b15 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 7b9856577..da64e3c59 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Hubungi Dukungan Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Permintaan Kontak Tertunda"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Jumlah minimum yang dapat Anda kirim adalah %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index 6aa7e05a3..0cd7b4c3b 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contatta il supporto di Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Richiesta di contatto in sospeso"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "L'importo minimo che puoi inviare è%@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index af6bd2300..4d764c846 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Coinbaseサポートに問い合わせる"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "連絡先リクエストを保留中"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "送金可能な最小金額は、%@です"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index 2f670683b..a877f4b77 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "코인베이스 지원센터에 문의하기"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "연락처 요청 대기 중"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "송금 가능한 최소 금액은 %@ 입니다"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index 5a32d3155..bf0a649f8 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index ce0ddd9dd..b88938417 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index 8f511db7a..e66cf57d3 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index 4a24a659a..100efda37 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Neem contact op met Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contactaanvraag in behandeling"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Het minimumbedrag dat je kan verzenden is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index 666e59efe..550e99fed 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Skontaktuj się z pomocą Coibase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Zaproszenie do kontaktów czeka na odpowiedź"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Minimalna kwota jaką możesz wysłać to %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index 1f907268d..a09e4b0e8 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contato com o Suporte Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Solicitação de Contato Pendente"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "A quantidade mínima que você pode enviar é %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index 346bad03f..6e13bfd97 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index 38890be96..08c1ee6fc 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Связаться с поддержкой Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Неподтверждённые запросы на добавление в контакты"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Минимальная сумма для отправки составляет %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 916a9c572..7e43a08e9 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Kontaktujte podporu Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Žiadosť o kontakt čaká na potvrdenie"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Minimálna suma, ktorú môžete poslať, je %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index dfdecc84c..ca2ac382c 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index 33864a364..27105ef96 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index df818ac3e..0e84f0ae6 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 175ceac2f..cde429ab5 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index bb5615804..753aed654 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index 92a38cb7b..bfcd1ef2f 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "ติดต่อฝ่ายสนับสนุน Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "คำขอติดต่อรอดำเนินการ"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "จำนวนเงินขั้นต่ำที่คุณสามารถส่งได้คือ %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 72b5f39fe..fe4019990 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Coinbase Destek Ekibii ile İletişime Geçin"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Bekleyen İletişim Talebi"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Gönderebileceğiniz minimum miktar %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index fc20abca3..9ccc47a4c 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Звернутися до служби підтримки Coinbase"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Непідтверджені запити на додавання до контактів"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "Мінімальна сума, яку ви можете надіслати, становить %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index 7f185ed30..a40934f37 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Yêu cầu liên hệ đang chờ"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index 71fec48ca..dbe96b738 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index 3b1a8b03e..267306408 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "Contact Coinbase Support"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "Contact Request Pending"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "The minimum amount you can send is %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index 18013987b..d83903248 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "联系 Coinbase客服"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "朋友申请等待中"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "您可以发送的最小额度是%@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index c9a063ade..cddf23ed1 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -517,6 +517,9 @@ Coinbase Two Factor Auth */ "Contact Coinbase Support" = "聯繫 Coinbase 支援服務"; +/* DashSpend */ +"Contact CTX Support" = "Contact CTX Support"; + /* No comment provided by engineer. */ "Contact Request Pending" = "有聯繫請求等待批准"; @@ -2407,6 +2410,9 @@ /* Coinbase */ "The minimum amount you can send is %@" = "您可以發送的最小金額是 %@"; +/* DashSpend */ +"The purchase limits for this merchant have changed. Please contact CTX Support for more information." = "The purchase limits for this merchant have changed. Please contact CTX Support for more information."; + /* Usernames */ "The username '%@' was blocked by the Dash Network. Please try again by requesting another username." = "The username '%@' was blocked by the Dash Network. Please try again by requesting another username."; From 1b6787d8b8b6219798781b99ad1282c77809826a Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Tue, 27 May 2025 20:28:09 +0700 Subject: [PATCH 10/10] chore: cleanup --- .../Model/Entites/CTXSpendModels.swift | 17 +++++++++++++ .../Transactions/SendCoinsService.swift | 25 ++++++------------- .../DashSpend/DashSpendPayViewModel.swift | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift index ea4b47c9c..3a844e022 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift @@ -1,3 +1,20 @@ +// +// 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 // MARK: - Request Models diff --git a/DashWallet/Sources/Models/Transactions/SendCoinsService.swift b/DashWallet/Sources/Models/Transactions/SendCoinsService.swift index b978ae983..8967b1626 100644 --- a/DashWallet/Sources/Models/Transactions/SendCoinsService.swift +++ b/DashWallet/Sources/Models/Transactions/SendCoinsService.swift @@ -68,9 +68,9 @@ public final class SendCoinsService: NSObject { return transaction } - // MARK: - Gift Card Payment Processing + // MARK: - BIP70 - func processGiftCardPayment(with paymentUrlString: String) async throws -> DSTransaction { + func payWithDashUrl(url paymentUrlString: String) async throws -> DSTransaction { // Create payment input from the URL guard let paymentUrl = URL(string: paymentUrlString) else { throw CTXSpendError.paymentProcessingError("Invalid payment URL") @@ -140,17 +140,14 @@ extension SendCoinsService: DWPaymentProcessorDelegate { } public func paymentProcessor(_ processor: DWPaymentProcessor, requestAmountWithDestination sendingDestination: String, details: DSPaymentProtocolDetails?, contactItem: DWDPBasicUserItem?) { - // Not needed for gift card payments - completePayment(transaction: nil, error: CTXSpendError.paymentProcessingError("Amount request not supported for gift cards")) + completePayment(transaction: nil, error: CTXSpendError.paymentProcessingError("Amount request not supported")) } public func paymentProcessor(_ processor: DWPaymentProcessor, requestUserActionTitle title: String?, message: String?, actionTitle: String, cancel cancelBlock: (() -> Void)?, actionBlock: (() -> Void)?) { - // Auto-confirm for gift card purchases actionBlock?() } public func paymentProcessor(_ processor: DWPaymentProcessor, confirmPaymentOutput paymentOutput: DWPaymentOutput) { - // Auto-confirm for gift card purchases processor.confirmPaymentOutput(paymentOutput) } @@ -162,19 +159,11 @@ extension SendCoinsService: DWPaymentProcessorDelegate { completePayment(transaction: transaction, error: nil) } - public func paymentProcessor(_ processor: DWPaymentProcessor, displayFileProcessResult result: String) { - // Not needed for gift card payments - } + public func paymentProcessor(_ processor: DWPaymentProcessor, displayFileProcessResult result: String) { } - public func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { - // Not needed for gift card payments - } + public func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { } - public func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { - // Progress is handled by the UI layer - } + public func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { } - public func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { - // Progress is handled by the UI layer - } + public func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { } } diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index 3b3681a98..39ca5b1ce 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -140,7 +140,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject { throw CTXSpendError.paymentProcessingError("No payment URL received") } - let transaction = try await sendCoinsService.processGiftCardPayment(with: paymentUrlString) + let transaction = try await sendCoinsService.payWithDashUrl(url: paymentUrlString) // Payment successful - save gift card information DSLogger.log("Payment transaction completed: \(transaction.txHashHexString)")