taler-typescript-core

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

commit 62f078545a272d0abff0b52d865e1159ed11d17e
parent e76071abac37fae340b8c126438a0b4f6553c857
Author: Florian Dold <florian@dold.me>
Date:   Fri, 13 Feb 2026 19:53:36 +0100

-refactor

Diffstat:
Mpackages/taler-wallet-core/src/refresh.ts | 123++++++++++++-------------------------------------------------------------------
1 file changed, 18 insertions(+), 105 deletions(-)

diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts @@ -23,7 +23,6 @@ * Imports. */ import { - AgeCommitment, AgeRestriction, AmountJson, AmountLike, @@ -35,7 +34,6 @@ import { codecForCoinHistoryResponse, codecForExchangeMeltResponse, codecForExchangeRevealMeltResponseV2, - CoinPublicKeyString, CoinRefreshRequest, CoinStatus, DenominationInfo, @@ -43,7 +41,6 @@ import { Duration, encodeCrock, ExchangeMeltRequestV2, - ExchangeRefreshRevealRequest, ExchangeRefreshRevealRequestV2, ExchangeRefundRequest, fnutil, @@ -90,11 +87,7 @@ import { TaskRunResultType, TransactionContext, } from "./common.js"; -import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; -import { - DerivedRefreshSession, - RefreshNewDenomInfo, -} from "./crypto/cryptoTypes.js"; +import { RefreshNewDenomInfo } from "./crypto/cryptoTypes.js"; import { CryptoApiStoppedError } from "./crypto/workers/crypto-dispatcher.js"; import { CoinAvailabilityRecord, @@ -116,8 +109,6 @@ import { import { selectWithdrawalDenominations } from "./denomSelection.js"; import { fetchFreshExchange, getScopeForAllExchanges } from "./exchanges.js"; import { - applyNotifyTransition, - BalanceEffect, constructTransactionIdentifier, isUnsuccessfulTransaction, } from "./transactions.js"; @@ -863,7 +854,7 @@ async function handleRefreshMeltGone( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(ctx.refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { return; } @@ -882,10 +873,9 @@ async function handleRefreshMeltGone( throw Error("db invariant failed: missing refresh session in database"); } refreshSession.lastError = errDetails; - await destroyRefreshSession(ctx.wex, tx, rg, refreshSession); - await tx.refreshGroups.put(rg); - await ctx.updateTransactionMeta(tx); await tx.refreshSessions.put(refreshSession); + await destroyRefreshSession(ctx.wex, tx, rg, refreshSession); + await h.update(rg); }, ); } @@ -983,7 +973,7 @@ async function handleRefreshMeltConflict( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(ctx.refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { return; } @@ -1005,9 +995,8 @@ async function handleRefreshMeltConflict( ); } refreshSession.lastError = errDetails; - await tx.refreshGroups.put(rg); - await ctx.updateTransactionMeta(tx); await tx.refreshSessions.put(refreshSession); + await h.update(rg); } else { // Try again with new denoms! rg.inputPerCoin[coinIndex] = historyJson.balance; @@ -1055,7 +1044,7 @@ async function handleRefreshMeltNotFound( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(ctx.refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { return; } @@ -1073,73 +1062,14 @@ async function handleRefreshMeltNotFound( if (!refreshSession) { throw Error("db invariant failed: missing refresh session in database"); } - await destroyRefreshSession(ctx.wex, tx, rg, refreshSession); refreshSession.lastError = errDetails; - await tx.refreshGroups.put(rg); - await ctx.updateTransactionMeta(tx); await tx.refreshSessions.put(refreshSession); + await destroyRefreshSession(ctx.wex, tx, rg, refreshSession); + await h.update(rg); }, ); } -export async function assembleRefreshRevealRequest(args: { - cryptoApi: TalerCryptoInterface; - derived: DerivedRefreshSession; - norevealIndex: number; - oldCoinPub: CoinPublicKeyString; - oldCoinPriv: string; - newDenoms: { - denomPubHash: string; - count: number; - }[]; - oldAgeCommitment?: AgeCommitment; -}): Promise<ExchangeRefreshRevealRequest> { - const { - derived, - norevealIndex, - cryptoApi, - oldCoinPriv, - oldCoinPub, - newDenoms, - } = args; - const privs = Array.from(derived.transferPrivs); - privs.splice(norevealIndex, 1); - - const planchets = derived.planchets[norevealIndex]; - if (!planchets) { - throw Error("refresh index error"); - } - - const newDenomsFlat: string[] = []; - const linkSigs: string[] = []; - - for (let i = 0; i < newDenoms.length; i++) { - const dsel = newDenoms[i]; - for (let j = 0; j < dsel.count; j++) { - const newCoinIndex = linkSigs.length; - const linkSig = await cryptoApi.signCoinLink({ - coinEv: planchets[newCoinIndex].coinEv, - newDenomHash: dsel.denomPubHash, - oldCoinPriv: oldCoinPriv, - oldCoinPub: oldCoinPub, - transferPub: derived.transferPubs[norevealIndex], - }); - linkSigs.push(linkSig.sig); - newDenomsFlat.push(dsel.denomPubHash); - } - } - - const req: ExchangeRefreshRevealRequest = { - coin_evs: planchets.map((x) => x.coinEv), - new_denoms_h: newDenomsFlat, - transfer_privs: privs, - transfer_pub: derived.transferPubs[norevealIndex], - link_sigs: linkSigs, - old_age_commitment: args.oldAgeCommitment?.publicKeys, - }; - return req; -} - async function refreshReveal( wex: WalletExecutionContext, refreshGroupId: string, @@ -1339,7 +1269,7 @@ async function refreshReveal( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { logger.warn("no refresh session found"); return; @@ -1383,8 +1313,7 @@ async function refreshReveal( car.freshCoinCount++; await tx.coinAvailability.put(car); } - await tx.refreshGroups.put(rg); - await ctx.updateTransactionMeta(tx); + await h.update(rg); }, ); logger.trace("refresh finished (end of reveal)"); @@ -1407,7 +1336,7 @@ async function handleRefreshRevealError( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(ctx.refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { return; } @@ -1427,9 +1356,8 @@ async function handleRefreshRevealError( } refreshSession.lastError = errDetails; await destroyRefreshSession(ctx.wex, tx, rg, refreshSession); - await tx.refreshGroups.put(rg); await tx.refreshSessions.put(refreshSession); - await ctx.updateTransactionMeta(tx); + await h.update(rg); }, ); } @@ -1521,7 +1449,7 @@ export async function processRefreshGroup( ], }, async (tx) => { - const rg = await tx.refreshGroups.get(refreshGroupId); + const [rg, h] = await ctx.getRecordHandle(tx); if (!rg) { return false; } @@ -1531,8 +1459,6 @@ export async function processRefreshGroup( default: return false; } - const oldTxState = computeRefreshTransactionState(rg); - const oldStId = rg.operationStatus; const allFinal = fnutil.all( rg.statusPerCoin, (x) => @@ -1555,19 +1481,7 @@ export async function processRefreshGroup( rg.operationStatus = RefreshOperationStatus.Finished; } await makeCoinsVisible(wex, tx, ctx.transactionId); - await tx.refreshGroups.put(rg); - await ctx.updateTransactionMeta(tx); - const newTxState = computeRefreshTransactionState(rg); - applyNotifyTransition(tx.notify, ctx.transactionId, { - oldTxState, - newTxState, - balanceEffect: - rg.operationStatus === RefreshOperationStatus.Failed - ? BalanceEffect.Any - : BalanceEffect.PreserveUserVisible, - oldStId, - newStId: rg.operationStatus, - }); + await h.update(rg); return true; } return false; @@ -1897,14 +1811,14 @@ export async function createRefreshGroup( }; } -export async function redenominateRefresh( +async function redenominateRefresh( wex: WalletExecutionContext, refreshGroupId: string, ): Promise<TaskRunResult> { const ctx = new RefreshTransactionContext(wex, refreshGroupId); logger.info(`re-denominating refresh group ${refreshGroupId}`); return await wex.db.runAllStoresReadWriteTx({}, async (tx) => { - const refreshGroup = await tx.refreshGroups.get(refreshGroupId); + const [refreshGroup, h] = await ctx.getRecordHandle(tx); if (!refreshGroup) { return TaskRunResult.finished(); } @@ -1948,8 +1862,7 @@ export async function redenominateRefresh( ); refreshGroup.operationStatus = RefreshOperationStatus.Pending; - await tx.refreshGroups.put(refreshGroup); - await ctx.updateTransactionMeta(tx); + await h.update(refreshGroup); return TaskRunResult.progress(); }); }