taler-typescript-core

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

commit cc93bf0a7c79e6bf62a28a4e81d67956393b5b8b
parent 475ac2e513e2b7a1b576592749038ee4ec61d3e8
Author: Florian Dold <florian@dold.me>
Date:   Mon, 15 Sep 2025 14:21:17 +0200

wallet-core: fixup for missing exchanges in pay-merchant transactions

Some old wallets did not set this field properly.

Diffstat:
Mpackages/taler-wallet-core/src/db.ts | 48++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+), 0 deletions(-)

diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts @@ -66,6 +66,7 @@ import { TokenIssuePublicKey, TokenUseSig, TransactionIdStr, + TransactionType, UnblindedDenominationSignature, WireInfo, WithdrawalExchangeAccountDetails, @@ -90,6 +91,7 @@ import { describeStoreV2, openDatabase, } from "./query.js"; +import { constructTransactionIdentifier } from "./transactions.js"; /** * This file contains the database schema of the Taler wallet together @@ -3601,9 +3603,55 @@ export const walletDbFixups: FixupDescription[] = [ fn: fixup20250908TopsBlunder, name: "fixup20250908TopsBlunder", }, + // Removing this would cause old transactions + // to show up under multip,e exchanges + { + fn: fixup20250915TransactionsScope, + name: "fixup20250915TransactionsScope", + }, ]; /** + * Some old payment transactions didn't correctly + * set the involved exchanges. + * + * This fixup sets the exchanges of a payment transaction + * based on the coin selection. + */ +async function fixup20250915TransactionsScope( + tx: WalletDbAllStoresReadWriteTransaction, +): Promise<void> { + await tx.purchases.iter().forEachAsync(async (rec) => { + if ( + (rec.exchanges?.length ?? 0) == 0 && + rec.payInfo?.payCoinSelection != null + ) { + const pcs = rec.payInfo.payCoinSelection.coinPubs; + const exchSet: Set<string> = new Set(); + for (const pc in pcs) { + const coin = await tx.coins.get(pc); + if (!coin) { + continue; + } + exchSet.add(coin.exchangeBaseUrl); + } + rec.exchanges = [...exchSet]; + rec.exchanges.sort(); + if (rec.exchanges.length == 0) { + // FIXME: Here we might want to do a SPURLOSE exception. + logger.warn( + `unable to fix up transaction ${constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId: rec.proposalId, + })}, could not reconstruct exchanges`, + ); + } + await tx.purchases.put(rec); + } + }); +} + +/** * TOPS accidentally revoked keys. * Make sure to re-request keys and re-do denom selection * for withdrawal groups with zero selected denominations.