commit 56100061b880d42db7c5cb33cfaefb85210f2870
parent 4527d4a9d89a56226e4318c47fa264b117c3e2f6
Author: Marc Stibane <marc@taler.net>
Date: Sat, 18 Apr 2026 07:55:30 +0200
haveProdBalance
Diffstat:
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/TalerWallet1/Controllers/Controller.swift b/TalerWallet1/Controllers/Controller.swift
@@ -105,6 +105,7 @@ class Controller: ObservableObject {
public static let shared = Controller()
private let symLog = SymLogC()
+ @Published var haveProdBalance: Bool = false
@Published var balances: [Balance] = []
@Published var scannedURLs: [ScannedURL] = []
@@ -272,7 +273,8 @@ class Controller: ObservableObject {
@MainActor
@discardableResult
func loadBalances(_ stack: CallStack,_ model: WalletModel) async -> Int? {
- if let reloaded = try? await model.getBalances(stack.push()) {
+ if let response = try? await model.getBalances(stack.push()) {
+ let reloaded = response.balances
if reloaded != balances {
for balance in reloaded {
let scope = balance.scopeInfo
@@ -283,6 +285,7 @@ class Controller: ObservableObject {
} else {
self.logger.log("••Same balances, no redraw")
}
+ haveProdBalance = response.haveProdBalance
return reloaded.count
}
return nil
@@ -431,7 +434,7 @@ class Controller: ObservableObject {
#if !TALER_WALLET
if developerMode {
try? await model.setConfig(setTesting: true)
- try? await model.devExperimentT(talerUri: "taler://dev-experiment/default-exchange-demo?val=1")
+// try? await model.devExperimentT(talerUri: "taler://dev-experiment/default-exchange-demo?val=1")
try? await model.devExperimentT(talerUri: "taler://dev-experiment/demo-shortcuts?val=KUDOS:4,KUDOS:8,KUDOS:16,KUDOS:32")
try? await model.setConfig(setTesting: false)
}
diff --git a/TalerWallet1/Model/Model+Balances.swift b/TalerWallet1/Model/Model+Balances.swift
@@ -68,6 +68,11 @@ extension Balance {
}
}
// MARK: -
+struct BalancesResponse: Decodable, Hashable, Sendable {
+ let haveProdBalance: Bool // if false, show DefaultExchange hint
+ let balances: [Balance]
+}
+
/// A request to get the balances held in the wallet.
fileprivate struct Balances: WalletBackendFormattedRequest {
func operation() -> String { "getBalances" }
@@ -75,16 +80,14 @@ fileprivate struct Balances: WalletBackendFormattedRequest {
struct Args: Encodable {} // no arguments needed
- struct Response: Decodable, Sendable { // list of balances
- var balances: [Balance]
- }
+ typealias Response = BalancesResponse
}
// MARK: -
extension WalletModel {
/// fetch Balances from Wallet-Core. No networking involved
- nonisolated func getBalances(_ stack: CallStack, viewHandles: Bool = false) async throws -> [Balance] {
+ nonisolated func getBalances(_ stack: CallStack, viewHandles: Bool = false) async throws -> BalancesResponse {
let request = Balances()
let response = try await sendRequest(request, viewHandles: viewHandles)
- return response.balances
+ return response
}
}
diff --git a/TalerWallet1/Model/Model+Exchange.swift b/TalerWallet1/Model/Model+Exchange.swift
@@ -15,6 +15,11 @@ struct OperationErrorInfo: Codable, Hashable {
var error: TalerErrorDetail
}
+enum ExchangeType: String, Codable {
+ case demo
+ case prod
+}
+
enum ExchangeEntryStatus: String, Codable {
case preset
case ephemeral
@@ -141,12 +146,14 @@ extension DefaultExchange: Identifiable {
/// A request to list exchanges names for a currency
fileprivate struct ListExchanges: WalletBackendFormattedRequest {
func operation() -> String { "listExchanges" }
- func args() -> Args { Args(filterByScope: scope, filterByExchangeEntryStatus: filterByStatus) }
+ func args() -> Args { Args(filterByScope: scope, filterByType: filterByType, filterByExchangeEntryStatus: filterByStatus) }
var scope: ScopeInfo?
+ var filterByType: ExchangeType?
var filterByStatus: ExchangeEntryStatus?
struct Args: Encodable {
var filterByScope: ScopeInfo?
+ var filterByType: ExchangeType?
var filterByExchangeEntryStatus: ExchangeEntryStatus?
}
struct Response: Decodable { // list of known exchanges
@@ -268,10 +275,13 @@ fileprivate struct RmvGlobalCurrency: WalletBackendFormattedRequest {
// MARK: -
extension WalletModel {
/// ask wallet-core for its list of known exchanges
- nonisolated func listExchanges(scope: ScopeInfo?, filterByStatus: ExchangeEntryStatus? = nil, viewHandles: Bool = false)
+ nonisolated func listExchanges(scope: ScopeInfo?, filterByType: ExchangeType? = nil,
+ filterByStatus: ExchangeEntryStatus? = nil, viewHandles: Bool = false)
async -> [Exchange] { // M for MainActor
do {
- let request = ListExchanges(scope: scope, filterByStatus: filterByStatus) // .used, .preset
+ let request = ListExchanges(scope: scope,
+ filterByType: filterByType, // .demo, .prod
+ filterByStatus: filterByStatus) // .used, .preset
let response = try await sendRequest(request, viewHandles: viewHandles)
return response.exchanges
} catch {