commit 5e2e3f3a1f6e53211a0312da9819a47404768f8e
parent 5d698c7bb4f38131c76f751f643093bbc4de75d6
Author: Florian Dold <florian@dold.me>
Date: Thu, 4 Dec 2025 17:02:32 +0100
wallet-core: fix accidental nested transaction
Diffstat:
2 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/packages/taler-wallet-core/src/coinSelection.ts b/packages/taler-wallet-core/src/coinSelection.ts
@@ -1504,48 +1504,63 @@ function getMaxDepositAmountForAvailableCoins(
};
}
-export async function getExchangesForDeposit(
+export async function getExchangesForDepositInTx(
wex: WalletExecutionContext,
+ tx: WalletDbReadOnlyTransaction<
+ [
+ "exchanges",
+ "exchangeDetails",
+ "globalCurrencyExchanges",
+ "globalCurrencyAuditors",
+ ]
+ >,
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 getExchangeDetailsInTx(tx, e.baseUrl);
- if (!details) {
- logger.trace(`skipping ${e.baseUrl}, no details`);
- continue;
- }
- if (req.currency !== details.currency) {
- logger.trace(`skipping ${e.baseUrl}, currency mismatch`);
- continue;
- }
- if (e.directDepositDisabled) {
- logger.trace(`skipping ${e.baseUrl}, wallet deposits disabled`);
+ const allExchanges = await tx.exchanges.iter().toArray();
+ for (const e of allExchanges) {
+ const details = await getExchangeDetailsInTx(tx, e.baseUrl);
+ if (!details) {
+ logger.trace(`skipping ${e.baseUrl}, no details`);
+ continue;
+ }
+ if (req.currency !== details.currency) {
+ logger.trace(`skipping ${e.baseUrl}, currency mismatch`);
+ continue;
+ }
+ if (e.directDepositDisabled) {
+ logger.trace(`skipping ${e.baseUrl}, wallet deposits disabled`);
+ continue;
+ }
+ if (req.restrictScope) {
+ const inScope = await checkExchangeInScopeTx(
+ tx,
+ e.baseUrl,
+ req.restrictScope,
+ );
+ if (!inScope) {
continue;
}
- if (req.restrictScope) {
- const inScope = await checkExchangeInScopeTx(
- tx,
- e.baseUrl,
- req.restrictScope,
- );
- if (!inScope) {
- continue;
- }
- }
- exchangeInfos.push({
- master_pub: details.masterPublicKey,
- priority: 1,
- url: e.baseUrl,
- });
}
- });
+ exchangeInfos.push({
+ master_pub: details.masterPublicKey,
+ priority: 1,
+ url: e.baseUrl,
+ });
+ }
return exchangeInfos;
}
+export async function getExchangesForDeposit(
+ wex: WalletExecutionContext,
+ req: { restrictScope?: ScopeInfo; currency: string },
+): Promise<Exchange[]> {
+ return await wex.db.runAllStoresReadOnlyTx({}, async (tx) => {
+ return await getExchangesForDepositInTx(wex, tx, req);
+ });
+}
+
/**
* Only used for unit testing getMaxDepositAmountForAvailableCoins.
*/
@@ -1570,10 +1585,14 @@ export async function getMaxDepositAmount(
},
async (tx): Promise<GetMaxDepositAmountResponse> => {
let restrictWireMethod: string | undefined = undefined;
- const exchangeInfos: Exchange[] = await getExchangesForDeposit(wex, {
- currency: req.currency,
- restrictScope: req.restrictScope,
- });
+ const exchangeInfos: Exchange[] = await getExchangesForDepositInTx(
+ wex,
+ tx,
+ {
+ currency: req.currency,
+ restrictScope: req.restrictScope,
+ },
+ );
if (req.depositPaytoUri) {
const p = parsePaytoUri(req.depositPaytoUri);
if (!p) {
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
@@ -268,7 +268,7 @@ import {
setDangerousTimetravel,
setGlobalLogLevelFromString,
stringifyScopeInfo,
- validateIban
+ validateIban,
} from "@gnu-taler/taler-util";
import {
readSuccessResponseJsonOrThrow,
@@ -448,7 +448,7 @@ import {
WalletApiOperation,
WalletCoreApiClient,
WalletCoreRequestType,
- WalletCoreResponseType
+ WalletCoreResponseType,
} from "./wallet-api-types.js";
import {
acceptBankIntegratedWithdrawal,
@@ -1961,7 +1961,7 @@ interface HandlerWithValidator<Tag extends WalletApiOperation> {
const handlers: { [T in WalletApiOperation]: HandlerWithValidator<T> } = {
[WalletApiOperation.ConvertIbanAccountFieldToPayto]: {
codec: codecForConvertIbanAccountFieldToPaytoRequest(),
- handler: handleConvertIbanAccountFieldToPayto
+ handler: handleConvertIbanAccountFieldToPayto,
},
[WalletApiOperation.ConvertIbanPaytoToAccountField]: {
codec: codecForConvertIbanPaytoToAccountFieldRequest(),