taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 03fedb848b1e0c7ab3db9819b40e849ce4fa7cd2
parent 92ef7a77119a3d38b5fe45b220abe55806eef52f
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
Date:   Tue, 16 Aug 2022 14:56:28 -0400

manual withdraw

Diffstat:
MTaler/Model/WithdrawModel.swift | 48++++++++++++++++++++++++++++++++++++++++++++++--
MTaler/Views/SettingsView.swift | 27+++++++++++++++++++++++++--
MTaler/WalletBackend.swift | 6+++---
3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/Taler/Model/WithdrawModel.swift b/Taler/Model/WithdrawModel.swift @@ -17,6 +17,18 @@ import Foundation import taler_swift +func paytoUriGetIban(uri: String) -> String { + let url = URL(string: uri)! + return url.lastPathComponent +} + +func paytoUriGetSubject(uri: String) -> String { + let url = URLComponents(string: uri)! + return url.queryItems!.first(where: { item in + item.name == "message" + })!.value!.removingPercentEncoding!.replacingOccurrences(of: "+", with: " ") +} + class WithdrawModel: ObservableObject { enum State { case begin @@ -27,6 +39,9 @@ class WithdrawModel: ObservableObject { effectiveAmount: Amount, tos: String, etag: String) + case manualTransfer(rawAmount: Amount, + effectiveAmount: Amount, + paytoUri: String) } var backend: WalletBackend @@ -73,6 +88,7 @@ class WithdrawModel: ObservableObject { // TODO: Use Combine instead DispatchQueue.main.async { if let res = response { + print(res) self.state = .promptTOS(rawAmount: rawAmount, effectiveAmount: effectiveAmount, tos: res.content, @@ -89,9 +105,9 @@ class WithdrawModel: ObservableObject { let oldState = self.state self.state = .loading switch oldState { - case .promptTOS(let rawAmount, let effectiveAmount, let tos, let etag): + case .promptTOS(_, _, _, let etag): let req = WalletBackendSetExchangeTermsOfServiceAccepted(exchangeBaseUrl: exchange.exchangeBaseUrl, - acceptedEtag: etag) + etag: etag) backend.sendFormattedRequest(request: req) { response, err in // TODO: Use Combine instead DispatchQueue.main.async { @@ -104,4 +120,32 @@ class WithdrawModel: ObservableObject { // TODO: Show error. } } + + func acceptWithdraw() { + // TODO: Include an option for a withdraw payto uri. + let oldState = self.state + self.state = .loading + switch oldState { + case .prompt(let rawAmount, let effectiveAmount): + let req = WalletBackendAcceptManualWithdrawalRequest(exchangeBaseUrl: exchange.exchangeBaseUrl, + amount: rawAmount) + backend.sendFormattedRequest(request: req) { response, err in + // TODO: Use Combine instead + DispatchQueue.main.async { + if let res = response { + // TODO: Error if there are no URIs. + self.state = .manualTransfer(rawAmount: rawAmount, + effectiveAmount: effectiveAmount, + paytoUri: res.exchangePaytoUris[0]) + } else { + // TODO: Handle error. + self.state = oldState + } + } + } + default: + self.state = oldState + // TODO: Show error. + } + } } diff --git a/Taler/Views/SettingsView.swift b/Taler/Views/SettingsView.swift @@ -104,13 +104,13 @@ struct WithdrawView: View { Text("Exchange") Text(model.exchange.name) Button { - // TODO + model.acceptWithdraw() } label: { Text("Confirm Withdraw") } } .navigationTitle("Withdraw") - case .promptTOS(let rawAmount, let effectiveAmount, let tos, let etag): + case .promptTOS(let rawAmount, let effectiveAmount, let tos, _): VStack { Text("Withdraw") Text(effectiveAmount.readableDescription) @@ -138,6 +138,29 @@ struct WithdrawView: View { } } .navigationTitle("Withdraw") + case .manualTransfer(let rawAmount, _, let paytoUri): + VStack { + Text("Exchange is ready for withdrawal!") + Text("To complete the process you need to wire \(rawAmount.readableDescription) to the exchange bank account.") + HStack { + Text("IBAN: ") + Text(paytoUriGetIban(uri: paytoUri)) + } + HStack { + Text("Subject: ") + Text(paytoUriGetSubject(uri: paytoUri)) + } + HStack { + Text("Chosen Amount: ") + Text(rawAmount.readableDescription) + } + HStack { + Text("Exchange: ") + Text(model.exchange.exchangeBaseUrl) + } + Text("Make sure to use the correct subject, otherwise the money will not arrive in this wallet.") + } + .navigationTitle("Withdraw") } } } diff --git a/Taler/WalletBackend.swift b/Taler/WalletBackend.swift @@ -388,11 +388,11 @@ struct WalletBackendGetExchangeTermsOfService: WalletBackendFormattedRequest { /// A request to mark an exchange's terms of service as accepted. struct WalletBackendSetExchangeTermsOfServiceAccepted: WalletBackendFormattedRequest { var exchangeBaseUrl: String - var acceptedEtag: String + var etag: String struct Args: Encodable { var exchangeBaseUrl: String - var acceptedEtag: String + var etag: String } struct Response: Decodable { @@ -404,7 +404,7 @@ struct WalletBackendSetExchangeTermsOfServiceAccepted: WalletBackendFormattedReq } func args() -> Args { - return Args(exchangeBaseUrl: exchangeBaseUrl, acceptedEtag: acceptedEtag) + return Args(exchangeBaseUrl: exchangeBaseUrl, etag: etag) } }