taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 9bc232be913350e18766e7b314927ea0e52c7880
parent cc93bf0a7c79e6bf62a28a4e81d67956393b5b8b
Author: Florian Dold <florian@dold.me>
Date:   Mon, 15 Sep 2025 14:29:49 +0200

wallet-core: disallow empty withdrawals

Diffstat:
Mpackages/taler-wallet-core/src/exchanges.ts | 2+-
Mpackages/taler-wallet-core/src/withdraw.ts | 17+++++++++++++++++
2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -1227,7 +1227,7 @@ async function checkExchangeEntryOutdated( * If the exchange entry doesn't exist, * a new ephemeral entry is created. */ -async function startUpdateExchangeEntry( +export async function startUpdateExchangeEntry( wex: WalletExecutionContext, exchangeBaseUrl: string, options: { forceUpdate?: boolean } = {}, diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -175,6 +175,7 @@ import { listExchanges, lookupExchangeByUri, markExchangeUsed, + startUpdateExchangeEntry, } from "./exchanges.js"; import { GenericKycStatusReq, @@ -3992,6 +3993,22 @@ export async function confirmWithdrawal( instructedAmount, req.forcedDenomSel, ); + // Disallow withdrawals with no coins, they don't make sense. + // We only make an exception for the dev experiment. + if ( + wex.ws.devExperimentState.pretendNoDenoms != true && + initialDenoms.selectedDenoms.length === 0 + ) { + // Just in case, force talking to the exchange again, + // so a retry of the withdrawal might work. + await startUpdateExchangeEntry(wex, exchange.exchangeBaseUrl, { + forceUpdate: true, + }); + throw TalerError.fromUncheckedDetail({ + code: TalerErrorCode.WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT, + hint: "No denominations could be selected for withdrawal", + }); + } } await ctx.transition(