commit 00bdbfe58348ed4d6cb70c85c656c86b2e2cd3fe
parent 1fa7b551a8869bd906e8af9d681887fb83d416e7
Author: Florian Dold <dold@taler.net>
Date: Tue, 28 Jul 2026 11:59:59 +0200
wallet: refresh the payer's coins when a peer-pull-debit expires
The coins are allocated when the invoice is accepted, so expiring without a
refresh left them stuck on a dead transaction and the money was lost.
Diffstat:
1 file changed, 21 insertions(+), 0 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
@@ -228,6 +228,27 @@ export class PeerPullDebitTransactionContext implements TransactionContext {
if (rec?.status != fromSt) {
return;
}
+ if (rec.coinSel) {
+ // The purse is gone, so the coins we allocated for it never reached
+ // anyone. Without the refresh they would stay allocated to this dead
+ // transaction and the money would be lost.
+ const coinPubs: CoinRefreshRequest[] = [];
+ for (let i = 0; i < rec.coinSel.coinPubs.length; i++) {
+ coinPubs.push({
+ amount: rec.coinSel.contributions[i],
+ coinPub: rec.coinSel.coinPubs[i],
+ });
+ }
+ const refresh = await createRefreshGroup(
+ wex,
+ tx,
+ Amounts.currencyOf(rec.totalCostEstimated),
+ coinPubs,
+ RefreshReason.AbortPeerPullDebit,
+ this.transactionId,
+ );
+ rec.abortRefreshGroupId = refresh.refreshGroupId;
+ }
rec.status = PeerPullDebitRecordStatus.Expired;
await h.update(rec, "expire");
});