commit 1ba58720d4ef0806107e6043663fc495b57f91e2
parent 6affddc50527a8a4176e334166bff6b63c646ca6
Author: Florian Dold <dold@taler.net>
Date: Thu, 20 Aug 2026 19:06:45 +0200
wallet-core: price impossible refreshes as full loss
Diffstat:
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/packages/taler-wallet-core/src/refresh.test.ts b/packages/taler-wallet-core/src/refresh.test.ts
@@ -0,0 +1,32 @@
+/*
+ This file is part of GNU Taler
+ (C) 2026 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+import { Amounts, DenominationInfo } from "@gnu-taler/taler-util";
+import assert from "node:assert";
+import { test } from "node:test";
+import { getTotalRefreshCostInternal } from "./refresh.js";
+
+test("an impossible refresh costs the full remaining amount", () => {
+ const amountLeft = Amounts.parseOrThrow("TESTKUDOS:4");
+ const refreshedDenom = {
+ value: "TESTKUDOS:5",
+ feeRefresh: "TESTKUDOS:0.1",
+ } as DenominationInfo;
+
+ assert.deepStrictEqual(
+ getTotalRefreshCostInternal([], refreshedDenom, amountLeft),
+ amountLeft,
+ );
+});
diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts
@@ -440,7 +440,7 @@ export async function getTotalRefreshCosts(
* Considers refresh fees, withdrawal fees after refresh and amounts too small
* to refresh.
*/
-function getTotalRefreshCostInternal(
+export function getTotalRefreshCostInternal(
denoms: WalletDenomination[],
refreshedDenom: DenominationInfo,
amountLeft: AmountJson,
@@ -450,6 +450,9 @@ function getTotalRefreshCostInternal(
refreshedDenom.value
}, amount left ${Amounts.stringify(amountLeft)}`,
);
+ if (denoms.length === 0) {
+ return Amounts.copy(amountLeft);
+ }
const withdrawAmount = Amounts.sub(
amountLeft,
refreshedDenom.feeRefresh,