taler-typescript-core

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

commit 3e909773dd1788b0d10f0745b213e8211f1c6b15
parent e405e047527fe2790b6a36ad6733551b58d74a06
Author: Florian Dold <florian@dold.me>
Date:   Mon, 15 Jun 2026 19:08:37 +0200

wallet-core: allow aborting peer-pull-debit transactions without coin selection

Diffstat:
Mpackages/taler-wallet-core/src/pay-peer-pull-debit.ts | 54+++++++++++++++++++++++-------------------------------
1 file changed, 23 insertions(+), 31 deletions(-)

diff --git a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts @@ -93,7 +93,6 @@ import { parseTransactionIdentifier, } from "./transactions.js"; import { WalletExecutionContext, walletExchangeClient } from "./wallet.js"; -import { updateWithdrawalDenomsForCurrency } from "./withdraw.js"; const logger = new Logger("pay-peer-pull-debit.ts"); @@ -308,16 +307,6 @@ export class PeerPullDebitTransactionContext implements TransactionContext { } async userAbortTransaction(reason?: TalerErrorDetail): Promise<void> { - const oldRec = await this.wex.runLegacyWalletDbTx(async (tx) => { - const [rec, _] = await this.getRecordHandle(tx); - return rec; - }); - if (!oldRec) { - return; - } - const currency = Amounts.currencyOf(oldRec.amount); - await updateWithdrawalDenomsForCurrency(this.wex, currency); - await this.wex.runLegacyWalletDbTx(async (tx) => { const [pi, h] = await this.getRecordHandle(tx); if (!pi) { @@ -334,28 +323,31 @@ export class PeerPullDebitTransactionContext implements TransactionContext { const coinPubs: CoinRefreshRequest[] = []; if (!pi.coinSel) { - throw Error("invalid db state"); - } + // We didn't even select coins yet, abort immediately. + // Can happen for DBs that still have a prospective + // coin selection. + pi.status = PeerPullDebitRecordStatus.Aborted; + pi.abortReason = reason; + } else { + for (let i = 0; i < pi.coinSel.coinPubs.length; i++) { + coinPubs.push({ + amount: pi.coinSel.contributions[i], + coinPub: pi.coinSel.coinPubs[i], + }); + } + const refresh = await createRefreshGroup( + this.wex, + tx, + currency, + coinPubs, + RefreshReason.AbortPeerPullDebit, + this.transactionId, + ); - for (let i = 0; i < pi.coinSel.coinPubs.length; i++) { - coinPubs.push({ - amount: pi.coinSel.contributions[i], - coinPub: pi.coinSel.coinPubs[i], - }); + pi.status = PeerPullDebitRecordStatus.AbortingRefresh; + pi.abortRefreshGroupId = refresh.refreshGroupId; + pi.abortReason = reason; } - - const refresh = await createRefreshGroup( - this.wex, - tx, - currency, - coinPubs, - RefreshReason.AbortPeerPullDebit, - this.transactionId, - ); - - pi.status = PeerPullDebitRecordStatus.AbortingRefresh; - pi.abortRefreshGroupId = refresh.refreshGroupId; - pi.abortReason = reason; await h.update(pi); }); await this.wex.taskScheduler.resetTask(this.taskId);