taler-ios

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

Model+Balances.swift (2384B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-25 Taler Systems S.A.
      3  * See LICENSE.md
      4  */
      5 /**
      6  * @author Marc Stibane
      7  */
      8 import Foundation
      9 import taler_swift
     10 
     11 // MARK: -
     12 
     13 enum BalanceFlag: String, Codable {
     14     case incomingAml = "incoming-aml"
     15     case incomingConfirmation = "incoming-confirmation"
     16     case incomingKyc = "incoming-kyc"
     17     case outgoingKyc = "outgoing-kyc"
     18 }
     19 
     20 /// A currency balance
     21 struct Balance: Identifiable, Decodable, Hashable, Sendable {
     22     var id: String {
     23         if let url = scopeInfo.url {
     24             return url
     25         }
     26         return scopeInfo.currency
     27     }
     28 
     29     var scopeInfo: ScopeInfo
     30     var available: Amount
     31     var pendingIncoming: Amount
     32     var pendingOutgoing: Amount
     33     var flags: [BalanceFlag]
     34 
     35     public static func == (lhs: Balance, rhs: Balance) -> Bool {
     36         lhs.scopeInfo == rhs.scopeInfo
     37         && lhs.available == rhs.available
     38         && lhs.pendingIncoming == rhs.pendingIncoming
     39         && lhs.pendingOutgoing == rhs.pendingOutgoing
     40         && lhs.flags == rhs.flags
     41     }
     42 
     43     public func hash(into hasher: inout Hasher) {
     44         hasher.combine(scopeInfo)
     45         hasher.combine(available)
     46         hasher.combine(pendingIncoming)
     47         hasher.combine(pendingOutgoing)
     48         hasher.combine(flags)
     49     }
     50 }
     51 extension Balance {
     52     static func nonZeroBalances(_ balances: [Balance]) -> [Balance] {
     53         balances.filter { balance in
     54             !balance.available.isZero
     55         }
     56     }
     57     static func firstNonZero(_ balances: [Balance]) -> Balance? {
     58         balances.first { balance in
     59             !balance.available.isZero
     60         }
     61     }
     62 }
     63 // MARK: -
     64 /// A request to get the balances held in the wallet.
     65 fileprivate struct Balances: WalletBackendFormattedRequest {
     66     func operation() -> String { "getBalances" }
     67     func args() -> Args { Args() }
     68 
     69     struct Args: Encodable {}                           // no arguments needed
     70 
     71     struct Response: Decodable, Sendable {              // list of balances
     72         var balances: [Balance]
     73     }
     74 }
     75 // MARK: -
     76 extension WalletModel {
     77     /// fetch Balances from Wallet-Core. No networking involved
     78     nonisolated func getBalances(_ stack: CallStack, viewHandles: Bool = false) async throws -> [Balance] {
     79         let request = Balances()
     80         let response = try await sendRequest(request, viewHandles: viewHandles)
     81         return response.balances
     82     }
     83 }