commit 8e213e9dd027da6f51f2bb7a23a0fa24fed84041
parent 0faa2624a4c8c98b9b6ea19ff15ce80de9f6b90c
Author: Florian Dold <florian@dold.me>
Date: Sun, 3 Aug 2025 16:48:05 +0200
wallet-core: fix computation of viable exchanges for deposit when multiple exchanges are present for the same currency
Diffstat:
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts
@@ -51,6 +51,7 @@
*/
import { GlobalIDB } from "@gnu-taler/idb-bridge";
import {
+ AllowedExchangeInfo,
AmountJson,
AmountLike,
Amounts,
@@ -103,19 +104,27 @@ interface WalletBalance {
flagOutgoingKyc: boolean;
}
-/**
- * Compute the available amount that the wallet expects to get
- * out of a refresh group.
- */
-function computeRefreshGroupAvailableAmount(r: RefreshGroupRecord): AmountJson {
+function computeRefreshGroupAvailableAmountForExchanges(
+ r: RefreshGroupRecord,
+ restrictExchanges: AllowedExchangeInfo[] | undefined,
+): AmountJson {
// Don't count finished refreshes, since the refresh already resulted
// in coins being added to the wallet.
let available = Amounts.zeroOfCurrency(r.currency);
if (r.timestampFinished) {
return available;
}
- for (let i = 0; i < r.oldCoinPubs.length; i++) {
- available = Amounts.add(available, r.expectedOutputPerCoin[i]).amount;
+ if (!r.infoPerExchange) {
+ return available;
+ }
+ for (const exch of Object.keys(r.infoPerExchange)) {
+ const pe = r.infoPerExchange[exch];
+ if (
+ restrictExchanges == null ||
+ restrictExchanges.find((x) => x.exchangeBaseUrl === exch) != null
+ ) {
+ available = Amounts.add(available, pe.outputEffective).amount;
+ }
}
return available;
}
@@ -882,10 +891,11 @@ export async function getPaymentBalanceDetailsInTx(
if (r.currency != req.currency) {
return;
}
- d.balanceAvailable = Amounts.add(
- d.balanceAvailable,
- computeRefreshGroupAvailableAmount(r),
- ).amount;
+ const balRefresh = computeRefreshGroupAvailableAmountForExchanges(
+ r,
+ req.restrictExchanges?.exchanges,
+ );
+ d.balanceAvailable = Amounts.add(d.balanceAvailable, balRefresh).amount;
});
return d;
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
@@ -1983,12 +1983,18 @@ async function getExchangesForDeposit(
wex: WalletExecutionContext,
req: { restrictScope?: ScopeInfo; currency: string },
): Promise<Exchange[]> {
+ logger.trace(`getting exchanges for deposit ${j2s(req)}`);
const exchangeInfos: Exchange[] = [];
await wex.db.runAllStoresReadOnlyTx({}, async (tx) => {
const allExchanges = await tx.exchanges.iter().toArray();
for (const e of allExchanges) {
const details = await getExchangeWireDetailsInTx(tx, e.baseUrl);
- if (!details || req.currency !== details.currency) {
+ if (!details) {
+ logger.trace(`skipping ${e.baseUrl}, no details`);
+ continue;
+ }
+ if (req.currency !== details.currency) {
+ logger.trace(`skipping ${e.baseUrl}, currency mismatch`);
continue;
}
if (req.restrictScope) {
@@ -1998,7 +2004,7 @@ async function getExchangesForDeposit(
req.restrictScope,
);
if (!inScope) {
- break;
+ continue;
}
}
exchangeInfos.push({