commit c429eb06c6e67557834af4102461542b90c8218f
parent 689e76e903ab94171f8b1e2a7479e06c703ecfe5
Author: Marc Stibane <marc@taler.net>
Date: Mon, 9 Dec 2024 18:21:36 +0100
bank accounts
Diffstat:
5 files changed, 94 insertions(+), 60 deletions(-)
diff --git a/TalerWallet1/Model/Model+Deposit.swift b/TalerWallet1/Model/Model+Deposit.swift
@@ -165,19 +165,20 @@ extension WalletModel {
}
}
// MARK: -
-struct KnownBankAccountsInfo: Decodable, Hashable {
+struct BankAccountsInfo: Decodable, Hashable {
+ var bankAccountId: String
var paytoUri: String
var kycCompleted: Bool
- var currencies: [String]
- var alias: String?
+ var currencies: [String]?
+ var label: String?
}
-struct KnownBankAccounts: Decodable, Hashable {
- var accounts: [KnownBankAccountsInfo]
+struct BankAccounts: Decodable, Hashable {
+ var accounts: [BankAccountsInfo]
}
-/// A request to list know bank accounts.
-fileprivate struct ListKnownBankAccounts: WalletBackendFormattedRequest {
- typealias Response = KnownBankAccounts
- func operation() -> String { "listKnownBankAccounts" }
+/// A request to list known bank accounts.
+fileprivate struct ListBankAccounts: WalletBackendFormattedRequest {
+ typealias Response = BankAccounts
+ func operation() -> String { "listBankAccounts" }
func args() -> Args { Args(currency: currency) }
var currency: String?
struct Args: Encodable {
@@ -186,53 +187,85 @@ fileprivate struct ListKnownBankAccounts: WalletBackendFormattedRequest {
}
extension WalletModel {
/// ask for known accounts. No networking
- nonisolated func listKnownBankAccounts(_ currency: String? = nil, viewHandles: Bool = false)
- async throws -> [KnownBankAccountsInfo] {
- let request = ListKnownBankAccounts(currency: currency)
+ nonisolated func listBankAccounts(_ currency: String? = nil, viewHandles: Bool = false)
+ async throws -> [BankAccountsInfo] {
+ let request = ListBankAccounts(currency: currency)
let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
return response.accounts
}
}
+/// A request to get one bank account.
+fileprivate struct GetBankAccountById: WalletBackendFormattedRequest {
+ typealias Response = BankAccountsInfo
+ func operation() -> String { "getBankAccountById" }
+ func args() -> Args { Args(bankAccountId: bankAccountId) }
+ var bankAccountId: String
+ struct Args: Encodable {
+ var bankAccountId: String
+ }
+}
+extension WalletModel {
+ /// ask for a specific account. No networking
+ nonisolated func getBankAccountById(_ bankAccountId: String, viewHandles: Bool = false)
+ async throws -> BankAccountsInfo {
+ let request = GetBankAccountById(bankAccountId: bankAccountId)
+ let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
+ return response
+ }
+}
+
+struct AddBankAccountResponse: Decodable, Hashable {
+ var bankAccountId: String // Identifier of the added bank account
+}
/// A request to add a known bank account.
-fileprivate struct AddKnownBankAccount: WalletBackendFormattedRequest {
- struct Response: Decodable {} // no result - getting no error back means success
- func operation() -> String { "addKnownBankAccount" }
- func args() -> Args { Args(paytoUri: uri, alias: alias, replacePaytoUri: replaceUri) }
+fileprivate struct AddBankAccount: WalletBackendFormattedRequest {
+ typealias Response = AddBankAccountResponse
+ func operation() -> String { "addBankAccount" }
+ func args() -> Args { Args(paytoUri: uri,
+ label: label,
+ currencies: currencies,
+ replacePaytoUri: replaceUri) }
var uri: String
- var alias: String
+ var label: String
+ var currencies: [String]?
var replaceUri: String?
struct Args: Encodable {
var paytoUri: String // bank account that should be added
- var alias: String // Human-readable alias / label
+ var label: String // Human-readable label
var currencies: [String]? // currencies supported by the bank (if known)
var replacePaytoUri: String? // account that this new account should replace
}
}
extension WalletModel {
/// add (or update) a known account. No networking
- nonisolated func addKnownBankAccount(_ uri: String, alias: String, replaceUri: String? = nil, viewHandles: Bool = false)
- async throws {
- let request = AddKnownBankAccount(uri: uri, alias: alias, replaceUri: replaceUri)
- _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
+ nonisolated func addBankAccount(_ uri: String,
+ label: String,
+ currencies: [String]? = nil,
+ replaceUri: String? = nil,
+ viewHandles: Bool = false)
+ async throws -> String {
+ let request = AddBankAccount(uri: uri, label: label, currencies: currencies, replaceUri: replaceUri)
+ let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
+ return response.bankAccountId
}
}
/// A request to forget a known bank account.
-fileprivate struct ForgetKnownBankAccount: WalletBackendFormattedRequest {
+fileprivate struct ForgetBankAccount: WalletBackendFormattedRequest {
struct Response: Decodable {} // no result - getting no error back means success
- func operation() -> String { "forgetKnownBankAccount" }
- func args() -> Args { Args(paytoUri: uri) }
- var uri: String
+ func operation() -> String { "forgetBankAccount" }
+ func args() -> Args { Args(bankAccountId: accountId) }
+ var accountId: String
struct Args: Encodable {
- var paytoUri: String // bank account that should be forgotten
+ var bankAccountId: String // bank account that should be forgotten
}
}
extension WalletModel {
/// add a known account. No networking
- nonisolated func forgetKnownBankAccount(_ uri: String, viewHandles: Bool = false)
- async throws {
- let request = ForgetKnownBankAccount(uri: uri)
+ nonisolated func forgetBankAccount(_ accountId: String, viewHandles: Bool = false)
+ async throws {
+ let request = ForgetBankAccount(accountId: accountId)
_ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
}
}
diff --git a/TalerWallet1/Views/Actions/Banking/DepositIbanV.swift b/TalerWallet1/Views/Actions/Banking/DepositIbanV.swift
@@ -34,7 +34,7 @@ struct DepositIbanV: View {
@State private var currencySymbol: String = UNKNOWN
@State private var amountAvailable = Amount.zero(currency: EMPTYSTRING) // Update currency when used
@State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING) // Update currency when used
- @State private var bankAccounts: [KnownBankAccountsInfo] = []
+ @State private var bankAccounts: [BankAccountsInfo] = []
private var subjectTitle: String {
@@ -45,7 +45,7 @@ struct DepositIbanV: View {
@MainActor
private func viewDidLoad() async {
- if let accounts = try? await model.listKnownBankAccounts() {
+ if let accounts = try? await model.listBankAccounts() {
withAnimation { bankAccounts = accounts }
}
}
@@ -78,7 +78,7 @@ struct DepositIbanV: View {
let payURL = URL(string: account.paytoUri)
let iban = payURL?.iban
let xTaler = payURL?.xTaler
- let alias = account.alias
+ let alias = account.label
let kyc = account.kycCompleted ? String(localized: "verified")
: String(localized: "not yet verified")
diff --git a/TalerWallet1/Views/Settings/Bank/BankEditView.swift b/TalerWallet1/Views/Settings/Bank/BankEditView.swift
@@ -14,7 +14,7 @@ import SymLog
struct BankEditView: View {
private let symLog = SymLogV(0)
let stack: CallStack
- let account: KnownBankAccountsInfo
+ let account: BankAccountsInfo
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@@ -33,13 +33,13 @@ struct BankEditView: View {
@State private var accountHolder: String = EMPTYSTRING
@State private var iban: String = EMPTYSTRING
@State private var xTaler: String = EMPTYSTRING
- @State private var alias: String = EMPTYSTRING
+ @State private var label: String = EMPTYSTRING
@State private var paytoType: PaytoType = .iban
@State private var selected = 0
@FocusState private var focus:FocusedField?
enum FocusedField: Hashable {
- case accountHolder, iban, xTaler, alias
+ case accountHolder, iban, xTaler, label
}
// @MainActor
@@ -57,7 +57,7 @@ struct BankEditView: View {
let payURL = URL(string: account.paytoUri)
iban = payURL?.iban ?? EMPTYSTRING
xTaler = payURL?.xTaler ?? EMPTYSTRING
- alias = account.alias ?? EMPTYSTRING
+ label = account.label ?? EMPTYSTRING
if let queryParameters = payURL?.queryParameters {
let name = if let rcv = queryParameters["receiver-name"] {
rcv.replacingOccurrences(of: "+", with: SPACE)
@@ -169,9 +169,9 @@ struct BankEditView: View {
.talerFont(.title3)
.accessibilityHidden(true)
}
- TextField(minimalistic ? note : EMPTYSTRING, text: $alias)
+ TextField(minimalistic ? note : EMPTYSTRING, text: $label)
.accessibilityLabel(noteColon)
- .focused($focus, equals: .alias)
+ .focused($focus, equals: .label)
.talerFont(.title2)
.foregroundColor(WalletColors().fieldForeground) // text color
.background(WalletColors().fieldBackground)
diff --git a/TalerWallet1/Views/Settings/Bank/BankListView.swift b/TalerWallet1/Views/Settings/Bank/BankListView.swift
@@ -22,11 +22,7 @@ struct BankListView: View {
@State var showAddDialog: Bool = false
@State var newExchange: String = TESTEXCHANGE
- @State var newBankAccount = KnownBankAccountsInfo(paytoUri: EMPTYSTRING,
- kycCompleted: false,
- currencies: [],
- alias: nil)
- @State private var bankAccounts: [KnownBankAccountsInfo] = []
+ @State private var bankAccounts: [BankAccountsInfo] = []
@MainActor
func addExchange(_ exchange: String) -> Void {
@@ -42,7 +38,7 @@ struct BankListView: View {
@MainActor
private func viewDidLoad() async {
- if let accounts = try? await model.listKnownBankAccounts() {
+ if let accounts = try? await model.listBankAccounts() {
withAnimation { bankAccounts = accounts }
}
}
@@ -81,7 +77,7 @@ struct BankListView: View {
}
let addBankDest = BankEditView(stack: stack.push(),
- account: newBankAccount)
+ account: nil)
let actions = Group {
NavLink($showAddDialog) { addBankDest }
}
@@ -94,7 +90,7 @@ struct BankListView: View {
depositHint
ForEach(bankAccounts, id: \.self) { account in
BankSectionView(stack: stack.push(),
- account: account)
+ account: account)
// Text(account.paytoUri)
}
}
diff --git a/TalerWallet1/Views/Settings/Bank/BankSectionView.swift b/TalerWallet1/Views/Settings/Bank/BankSectionView.swift
@@ -14,7 +14,7 @@ import SymLog
struct BankSectionView: View {
private let symLog = SymLogV(0)
let stack: CallStack
- let account: KnownBankAccountsInfo
+ let account: BankAccountsInfo
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@@ -33,13 +33,13 @@ struct BankSectionView: View {
@State private var accountHolder: String = EMPTYSTRING
@State private var iban: String = EMPTYSTRING
@State private var xTaler: String = EMPTYSTRING
- @State private var alias: String = EMPTYSTRING
+ @State private var label: String = EMPTYSTRING
@State private var paytoType: PaytoType = .iban
@State private var selected = 0
@FocusState private var focus:FocusedField?
enum FocusedField: Hashable {
- case accountHolder, iban, xTaler, alias
+ case accountHolder, iban, xTaler, label
}
// @MainActor
@@ -57,7 +57,7 @@ struct BankSectionView: View {
let payURL = URL(string: account.paytoUri)
iban = payURL?.iban ?? EMPTYSTRING
xTaler = payURL?.xTaler ?? EMPTYSTRING
- alias = account.alias ?? EMPTYSTRING
+ label = account.label ?? EMPTYSTRING
if let queryParameters = payURL?.queryParameters {
let name = if let rcv = queryParameters["receiver-name"] {
rcv.replacingOccurrences(of: "+", with: SPACE)
@@ -105,18 +105,23 @@ struct BankSectionView: View {
account: account)
} label: {
VStack(alignment: .leading) {
- if account.currencies.count == 1 {
- BankSectionRow(title: String(localized: "Currency:"),
- value: account.currencies[0])
- } else {
- if !minimalistic { Text("Currencies:") }
- ForEach (account.currencies, id: \.self) { currency in
- Text(currency)
- .frame(maxWidth: .infinity, alignment: .trailing)
+ if let currencies = account.currencies {
+ if currencies.count == 1 {
+ BankSectionRow(title: String(localized: "Currency:"),
+ value: currencies[0])
+ } else {
+ if !minimalistic { Text("Currencies:") }
+ ForEach (currencies, id: \.self) { currency in
+ Text(currency)
+ .frame(maxWidth: .infinity, alignment: .trailing)
+ }
}
+ } else {
+ BankSectionRow(title: String(localized: "Currency:"),
+ value: "UNKNOWN")
}
BankSectionRow(title: String(localized: "Note:"),
- value: alias)
+ value: label)
BankSectionRow(title: String(localized: "Account holder:"),
value: accountHolder)
BankSectionRow(title: String(localized: "\(methodType):", comment: "methodType:"),