aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/balance.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-11-23 12:57:18 +0100
committerFlorian Dold <florian@dold.me>2023-11-23 12:57:18 +0100
commita0d746ad8d80490f9c2f1e017ff0c6a56b7d435c (patch)
treedc1f8ecebb07325c626ee06d1a7311faf09a0847 /packages/taler-wallet-core/src/operations/balance.ts
parent305c513c2bcc2b25fe57cf0ed9723781944f9f3f (diff)
downloadwallet-core-a0d746ad8d80490f9c2f1e017ff0c6a56b7d435c.tar.xz
wallet-core: implement balance flags for UI badges
Diffstat (limited to 'packages/taler-wallet-core/src/operations/balance.ts')
-rw-r--r--packages/taler-wallet-core/src/operations/balance.ts120
1 files changed, 85 insertions, 35 deletions
diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts
index 8034f78ea..6d396f6dd 100644
--- a/packages/taler-wallet-core/src/operations/balance.ts
+++ b/packages/taler-wallet-core/src/operations/balance.ts
@@ -54,6 +54,7 @@ import {
AllowedExchangeInfo,
AmountJson,
Amounts,
+ BalanceFlag,
BalancesResponse,
canonicalizeBaseUrl,
GetBalanceDetailRequest,
@@ -62,8 +63,11 @@ import {
ScopeType,
} from "@gnu-taler/taler-util";
import {
+ depositOperationNonfinalStatusRange,
+ DepositOperationStatus,
RefreshGroupRecord,
WalletStoresV1,
+ withdrawalGroupNonfinalRange,
WithdrawalGroupStatus,
} from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js";
@@ -81,6 +85,10 @@ interface WalletBalance {
available: AmountJson;
pendingIncoming: AmountJson;
pendingOutgoing: AmountJson;
+ flagIncomingKyc: boolean;
+ flagIncomingAml: boolean;
+ flagIncomingConfirmation: boolean;
+ flagOutgoingKyc: boolean;
}
/**
@@ -109,6 +117,7 @@ export async function getBalancesInsideTransaction(
coinAvailability: typeof WalletStoresV1.coinAvailability;
refreshGroups: typeof WalletStoresV1.refreshGroups;
withdrawalGroups: typeof WalletStoresV1.withdrawalGroups;
+ depositGroups: typeof WalletStoresV1.depositGroups;
}>,
): Promise<BalancesResponse> {
const balanceStore: Record<string, WalletBalance> = {};
@@ -124,6 +133,10 @@ export async function getBalancesInsideTransaction(
available: Amounts.zeroOfCurrency(currency),
pendingIncoming: Amounts.zeroOfCurrency(currency),
pendingOutgoing: Amounts.zeroOfCurrency(currency),
+ flagIncomingAml: false,
+ flagIncomingConfirmation: false,
+ flagIncomingKyc: false,
+ flagOutgoingKyc: false,
};
}
return balanceStore[currency];
@@ -145,42 +158,65 @@ export async function getBalancesInsideTransaction(
).amount;
});
+ await tx.withdrawalGroups.indexes.byStatus
+ .iter(withdrawalGroupNonfinalRange)
+ .forEach((wgRecord) => {
+ const b = initBalance(
+ Amounts.currencyOf(wgRecord.denomsSel.totalWithdrawCost),
+ );
+ switch (wgRecord.status) {
+ case WithdrawalGroupStatus.AbortedBank:
+ case WithdrawalGroupStatus.AbortedExchange:
+ case WithdrawalGroupStatus.FailedAbortingBank:
+ case WithdrawalGroupStatus.FailedBankAborted:
+ case WithdrawalGroupStatus.Done:
+ // Does not count as pendingIncoming
+ return;
+ case WithdrawalGroupStatus.PendingReady:
+ case WithdrawalGroupStatus.AbortingBank:
+ case WithdrawalGroupStatus.PendingAml:
+ b.flagIncomingAml = true;
+ break;
+ case WithdrawalGroupStatus.PendingKyc:
+ b.flagIncomingKyc = true;
+ break;
+ case WithdrawalGroupStatus.PendingQueryingStatus:
+ case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
+ case WithdrawalGroupStatus.SuspendedReady:
+ case WithdrawalGroupStatus.SuspendedRegisteringBank:
+ case WithdrawalGroupStatus.SuspendedKyc:
+ b.flagIncomingKyc = true;
+ break;
+ case WithdrawalGroupStatus.SuspendedAbortingBank:
+ case WithdrawalGroupStatus.SuspendedAml:
+ b.flagIncomingAml = true;
+ break;
+ case WithdrawalGroupStatus.PendingRegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
+ b.flagIncomingConfirmation = true;
+ break;
+ case WithdrawalGroupStatus.SuspendedQueryingStatus:
+ break;
+ default:
+ assertUnreachable(wgRecord.status);
+ }
+ b.pendingIncoming = Amounts.add(
+ b.pendingIncoming,
+ wgRecord.denomsSel.totalCoinValue,
+ ).amount;
+ });
+
// FIXME: Use indexing to filter out final transactions.
- await tx.withdrawalGroups.iter().forEach((wgRecord) => {
- switch (wgRecord.status) {
- case WithdrawalGroupStatus.AbortedBank:
- case WithdrawalGroupStatus.AbortedExchange:
- case WithdrawalGroupStatus.FailedAbortingBank:
- case WithdrawalGroupStatus.FailedBankAborted:
- case WithdrawalGroupStatus.Done:
- // Does not count as pendingIncoming
- return;
- case WithdrawalGroupStatus.PendingReady:
- case WithdrawalGroupStatus.AbortingBank:
- case WithdrawalGroupStatus.PendingAml:
- case WithdrawalGroupStatus.PendingKyc:
- case WithdrawalGroupStatus.PendingQueryingStatus:
- case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
- case WithdrawalGroupStatus.SuspendedReady:
- case WithdrawalGroupStatus.SuspendedRegisteringBank:
- case WithdrawalGroupStatus.SuspendedKyc:
- case WithdrawalGroupStatus.SuspendedAbortingBank:
- case WithdrawalGroupStatus.SuspendedAml:
- case WithdrawalGroupStatus.PendingRegisteringBank:
- case WithdrawalGroupStatus.PendingWaitConfirmBank:
- case WithdrawalGroupStatus.SuspendedQueryingStatus:
- break;
- default:
- assertUnreachable(wgRecord.status);
- }
- const b = initBalance(
- Amounts.currencyOf(wgRecord.denomsSel.totalWithdrawCost),
- );
- b.pendingIncoming = Amounts.add(
- b.pendingIncoming,
- wgRecord.denomsSel.totalCoinValue,
- ).amount;
- });
+ await tx.depositGroups.indexes.byStatus
+ .iter(depositOperationNonfinalStatusRange)
+ .forEach((dgRecord) => {
+ const b = initBalance(Amounts.currencyOf(dgRecord.amount));
+ switch (dgRecord.operationStatus) {
+ case DepositOperationStatus.SuspendedKyc:
+ case DepositOperationStatus.PendingKyc:
+ b.flagOutgoingKyc = true;
+ }
+ });
const balancesResponse: BalancesResponse = {
balances: [],
@@ -190,6 +226,16 @@ export async function getBalancesInsideTransaction(
.sort()
.forEach((c) => {
const v = balanceStore[c];
+ const flags: BalanceFlag[] = [];
+ if (v.flagIncomingAml) {
+ flags.push(BalanceFlag.IncomingAml);
+ }
+ if (v.flagIncomingKyc) {
+ flags.push(BalanceFlag.IncomingKyc);
+ }
+ if (v.flagIncomingConfirmation) {
+ flags.push(BalanceFlag.IncomingConfirmation);
+ }
balancesResponse.balances.push({
scopeInfo: {
type: ScopeType.Global,
@@ -198,8 +244,11 @@ export async function getBalancesInsideTransaction(
available: Amounts.stringify(v.available),
pendingIncoming: Amounts.stringify(v.pendingIncoming),
pendingOutgoing: Amounts.stringify(v.pendingOutgoing),
+ // FIXME: This field is basically not implemented, do we even need it?
hasPendingTransactions: false,
+ // FIXME: This field is basically not implemented, do we even need it?
requiresUserInput: false,
+ flags,
});
});
@@ -221,6 +270,7 @@ export async function getBalances(
x.refreshGroups,
x.purchases,
x.withdrawalGroups,
+ x.depositGroups,
])
.runReadOnly(async (tx) => {
return getBalancesInsideTransaction(ws, tx);