taler-typescript-core

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

commit 013de4e8de29155bd10d9955cd990f05a9ad9f8d
parent 7a22d181ff6eac813dcb78704b5a780f09dc4c00
Author: Florian Dold <dold@taler.net>
Date:   Wed, 22 Jul 2026 00:33:36 +0200

wallet: take the age mask from the denomination group being read

The mask was tracked across the whole /keys response, so a plain RSA
group following an age-restricted one inherited that group's mask.  The
mask goes into the denomination hash, so those denominations hashed to a
value the master signature does not cover and became unusable.

Diffstat:
Mpackages/taler-wallet-core/src/exchanges.ts | 14++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -1823,7 +1823,9 @@ export async function updateExchangeFromUrlHandler( logger.trace("updating exchange info in database"); - let ageMask = 0; + // Age mask advertised by the exchange, i.e. the one shared by its + // age-restricted denominations. Zero when it offers none. + let exchangeAgeMask = 0; let noFees = checkNoFees(keysInfo); let peerPaymentsDisabled = checkPeerPaymentsDisabled(keysInfo); @@ -1839,8 +1841,12 @@ export async function updateExchangeFromUrlHandler( } case "RSA": case "RSA+age_restricted": { - if (denomFamily.cipher === "RSA+age_restricted") { - ageMask = denomFamily.age_mask; + const ageMask = + denomFamily.cipher === "RSA+age_restricted" + ? denomFamily.age_mask + : 0; + if (ageMask !== 0) { + exchangeAgeMask = ageMask; } for (const denom of denomFamily.denoms) { const denomPub: DenominationPubKey = { @@ -1947,7 +1953,7 @@ export async function updateExchangeFromUrlHandler( globalFees, exchangeBaseUrl: r.baseUrl, wireInfo, - ageMask, + ageMask: exchangeAgeMask, walletBalanceLimits: keysInfo.wallet_balance_limit_without_kyc, hardLimits: keysInfo.hard_limits, zeroLimits: keysInfo.zero_limits,