taler-typescript-core

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

commit 3b91c7c8c1d0db457ad28cd832cbcc61e7b1cd2a
parent fdc2fdfa5c7a308d2d4600ba882a8b2c82dcc12e
Author: Florian Dold <dold@taler.net>
Date:   Sat, 18 Jul 2026 20:38:39 +0200

db: add recoup group and reserve accessors

Diffstat:
Mpackages/taler-wallet-core/src/common.ts | 4++--
Mpackages/taler-wallet-core/src/db-common.ts | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/db-indexeddb.ts | 87++++---------------------------------------------------------------------------
Mpackages/taler-wallet-core/src/dbtx-indexeddb.ts | 42++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/dbtx.ts | 30++++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/exchanges.ts | 46++++++++++++++++++++++------------------------
Mpackages/taler-wallet-core/src/pay-peer-common.ts | 17++++++-----------
Mpackages/taler-wallet-core/src/pay-peer-pull-credit.ts | 4++--
Mpackages/taler-wallet-core/src/recoup.ts | 34+++++++++++++++++-----------------
Mpackages/taler-wallet-core/src/wallet.ts | 2+-
Mpackages/taler-wallet-core/src/withdraw.ts | 2+-
11 files changed, 209 insertions(+), 141 deletions(-)

diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts @@ -69,6 +69,7 @@ import { WalletCoinHistory, WalletCoin, WalletDepositGroup, + WalletRecoupGroup, } from "./db-common.js"; import { ExchangeEntryRecord, @@ -77,7 +78,6 @@ import { PeerPushCreditRecord, PeerPushDebitRecord, PurchaseRecord, - RecoupGroupRecord, RefreshGroupRecord, WithdrawalGroupRecord, } from "./db-indexeddb.js"; @@ -829,7 +829,7 @@ export namespace TaskIdentifiers { export function forPay(purchaseRecord: PurchaseRecord): TaskIdStr { return `${PendingTaskType.Purchase}:${purchaseRecord.proposalId}` as TaskIdStr; } - export function forRecoup(recoupRecord: RecoupGroupRecord): TaskIdStr { + export function forRecoup(recoupRecord: WalletRecoupGroup): TaskIdStr { return `${PendingTaskType.Recoup}:${recoupRecord.recoupGroupId}` as TaskIdStr; } export function forDeposit(depositRecord: WalletDepositGroup): TaskIdStr { diff --git a/packages/taler-wallet-core/src/db-common.ts b/packages/taler-wallet-core/src/db-common.ts @@ -30,6 +30,7 @@ import { Amounts, DenominationInfo, TransferOptionRaw, + CoinRefreshRequest, CoinStatus, AgeCommitmentProof, TransactionIdStr, @@ -307,6 +308,87 @@ export interface WalletDepositGroup { }; } +/** + * Status of recoup operations that were grouped together. + * + * The remaining amount of involved coins should be set to zero + * in the same transaction that inserts the WalletRecoupGroup. + */ +export interface WalletRecoupGroup { + /** + * Unique identifier for the recoup group record. + */ + recoupGroupId: string; + + exchangeBaseUrl: string; + + operationStatus: RecoupOperationStatus; + + timestampStarted: DbPreciseTimestamp; + + timestampFinished: DbPreciseTimestamp | undefined; + + /** + * Public keys that identify the coins being recouped + * as part of this session. + * + * (Structured like this to enable multiEntry indexing in IndexedDB.) + */ + coinPubs: string[]; + + /** + * Array of flags to indicate whether the recoup finished on each individual coin. + */ + recoupFinishedPerCoin: boolean[]; + + /** + * Public keys of coins that should be scheduled for refreshing + * after all individual recoups are done. + */ + scheduleRefreshCoins: CoinRefreshRequest[]; +} + +/** + * Store for extra information about a reserve. + * + * Mostly used to store the private key for a reserve and to allow + * other records to reference the reserve key pair via a small row ID. + * + * In the future, we might also store KYC info about a reserve here. + * + * FIXME: Should reference exchange. + */ +export interface WalletReserve { + rowId?: number; + + reservePub: string; + + reservePriv: string; + + status?: ReserveRecordStatus; + + requirementRow?: number; + + /** + * Balance threshold that we're currently requesting KYC for. + */ + thresholdRequested?: AmountString; + + /** + * Balance threshold that we already have passed KYC for. + */ + thresholdGranted?: AmountString; + + /** + * Threshold that will trigger the next KYC. + */ + thresholdNext?: AmountString; + + kycAccessToken?: string; + + amlReview?: boolean; +} + export interface WalletWithdrawCoinSource { type: CoinSourceType.Withdraw; diff --git a/packages/taler-wallet-core/src/db-indexeddb.ts b/packages/taler-wallet-core/src/db-indexeddb.ts @@ -121,6 +121,8 @@ import { WalletDepositKycInfo, WalletDepositTrackingInfo, WalletDepositInfoPerExchange, + WalletRecoupGroup, + WalletReserve, WalletCoin, WalletCoinAvailability, WalletCoinHistory, @@ -1222,46 +1224,6 @@ export interface BankWithdrawUriRecord { reservePub: string; } -/** - * Status of recoup operations that were grouped together. - * - * The remaining amount of involved coins should be set to zero - * in the same transaction that inserts the RecoupGroupRecord. - */ -export interface RecoupGroupRecord { - /** - * Unique identifier for the recoup group record. - */ - recoupGroupId: string; - - exchangeBaseUrl: string; - - operationStatus: RecoupOperationStatus; - - timestampStarted: DbPreciseTimestamp; - - timestampFinished: DbPreciseTimestamp | undefined; - - /** - * Public keys that identify the coins being recouped - * as part of this session. - * - * (Structured like this to enable multiEntry indexing in IndexedDB.) - */ - coinPubs: string[]; - - /** - * Array of flags to indicate whether the recoup finished on each individual coin. - */ - recoupFinishedPerCoin: boolean[]; - - /** - * Public keys of coins that should be scheduled for refreshing - * after all individual recoups are done. - */ - scheduleRefreshCoins: CoinRefreshRequest[]; -} - export interface TombstoneRecord { /** * Tombstone ID, with the syntax "tmb:<type>:<key>". @@ -1522,47 +1484,6 @@ export interface PeerPullPaymentIncomingRecord { coinSel?: PeerPullPaymentCoinSelection; } -/** - * Store for extra information about a reserve. - * - * Mostly used to store the private key for a reserve and to allow - * other records to reference the reserve key pair via a small row ID. - * - * In the future, we might also store KYC info about a reserve here. - * - * FIXME: Should reference exchange. - */ -export interface ReserveRecord { - rowId?: number; - - reservePub: string; - - reservePriv: string; - - status?: ReserveRecordStatus; - - requirementRow?: number; - - /** - * Balance threshold that we're currently requesting KYC for. - */ - thresholdRequested?: AmountString; - - /** - * Balance threshold that we already have passed KYC for. - */ - thresholdGranted?: AmountString; - - /** - * Threshold that will trigger the next KYC. - */ - thresholdNext?: AmountString; - - kycAccessToken?: string; - - amlReview?: boolean; -} - export interface DbExchangeHandle { url: string; exchangeMasterPub: string; @@ -1971,7 +1892,7 @@ export const WalletIndexedDbStoresV1 = { ), reserves: describeStore( "reserves", - describeContents<ReserveRecord>({ + describeContents<WalletReserve>({ keyPath: "rowId", autoIncrement: true, }), @@ -2129,7 +2050,7 @@ export const WalletIndexedDbStoresV1 = { ), recoupGroups: describeStore( "recoupGroups", - describeContents<RecoupGroupRecord>({ + describeContents<WalletRecoupGroup>({ keyPath: "recoupGroupId", }), { diff --git a/packages/taler-wallet-core/src/dbtx-indexeddb.ts b/packages/taler-wallet-core/src/dbtx-indexeddb.ts @@ -34,6 +34,7 @@ import { assertUnreachable, ScopeType, WalletNotification, + checkDbInvariant, } from "@gnu-taler/taler-util"; import { GlobalIDB } from "@gnu-taler/idb-bridge"; import { @@ -54,6 +55,8 @@ import { WalletCoinHistory, WalletCoin, WalletDepositGroup, + WalletRecoupGroup, + WalletReserve, } from "./db-common.js"; import type { ExchangeEntryRecord, @@ -265,6 +268,45 @@ export class IdbWalletTransaction implements WalletDbTransaction { }); } + async getRecoupGroup( + recoupGroupId: string, + ): Promise<WalletRecoupGroup | undefined> { + const tx = this.tx; + return await tx.recoupGroups.get(recoupGroupId); + } + + async upsertRecoupGroup(rec: WalletRecoupGroup): Promise<void> { + const tx = this.tx; + await tx.recoupGroups.put(rec); + } + + async deleteRecoupGroup(recoupGroupId: string): Promise<void> { + const tx = this.tx; + await tx.recoupGroups.delete(recoupGroupId); + } + + async getReserve(reserveRowId: number): Promise<WalletReserve | undefined> { + const tx = this.tx; + return await tx.reserves.get(reserveRowId); + } + + async getReserveByReservePub( + reservePub: string, + ): Promise<WalletReserve | undefined> { + const tx = this.tx; + return await tx.reserves.indexes.byReservePub.get(reservePub); + } + + async upsertReserve(rec: WalletReserve): Promise<number> { + const tx = this.tx; + const res = await tx.reserves.put(rec); + checkDbInvariant( + typeof res.key === "number", + "reserve row id must be a number", + ); + return res.key; + } + async getDepositGroup( depositGroupId: string, ): Promise<WalletDepositGroup | undefined> { diff --git a/packages/taler-wallet-core/src/dbtx.ts b/packages/taler-wallet-core/src/dbtx.ts @@ -59,6 +59,8 @@ import { WalletCoinHistory, WalletCoin, WalletDepositGroup, + WalletRecoupGroup, + WalletReserve, } from "./db-common.js"; import type { ExchangeEntryRecord, @@ -174,6 +176,34 @@ export interface WalletDbTransaction { */ upsertContractTerms(rec: WalletContractTerms): Promise<void>; + getRecoupGroup( + recoupGroupId: string, + ): Promise<WalletRecoupGroup | undefined>; + + upsertRecoupGroup(rec: WalletRecoupGroup): Promise<void>; + + deleteRecoupGroup(recoupGroupId: string): Promise<void>; + + /** + * Get a reserve by its row id. + */ + getReserve(reserveRowId: number): Promise<WalletReserve | undefined>; + + /** + * Get a reserve by its reserve public key. + */ + getReserveByReservePub( + reservePub: string, + ): Promise<WalletReserve | undefined>; + + /** + * Create or update a reserve, returning its row id. + * + * The reserves store is auto-incrementing, and callers creating a new merge + * reserve need the generated id to reference it from the exchange entry. + */ + upsertReserve(rec: WalletReserve): Promise<number>; + getDepositGroup( depositGroupId: string, ): Promise<WalletDepositGroup | undefined>; diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -149,6 +149,7 @@ import { timestampProtocolFromDb, timestampProtocolToDb, WalletDenomination, + WalletReserve, } from "./db-common.js"; import { DenomFamilyParams, @@ -157,7 +158,6 @@ import { ExchangeDetailsRecord, ExchangeEntryRecord, ExchangeMigrationReason, - ReserveRecord, } from "./db-indexeddb.js"; import { createTimeline, @@ -386,7 +386,7 @@ async function makeExchangeListItem( tx: LegacyWalletTxHandle, r: ExchangeEntryRecord, exchangeDetails: ExchangeDetailsRecord | undefined, - reserveRec: ReserveRecord | undefined, + reserveRec: WalletReserve | undefined, lastError: TalerErrorDetail | undefined, ): Promise<ExchangeListItem> { let scopeInfo: ScopeInfo | undefined = undefined; @@ -519,9 +519,9 @@ export async function lookupExchangeByUri( const opRetryRecord = await tx.wtx.getOperationRetry( TaskIdentifiers.forExchangeUpdate(exchangeRec), ); - let reserveRec: ReserveRecord | undefined = undefined; + let reserveRec: WalletReserve | undefined = undefined; if (exchangeRec.currentMergeReserveRowId != null) { - reserveRec = await tx.reserves.get(exchangeRec.currentMergeReserveRowId); + reserveRec = await tx.wtx.getReserve(exchangeRec.currentMergeReserveRowId); checkDbInvariant(!!reserveRec, "reserve record not found"); } return await makeExchangeListItem( @@ -2905,9 +2905,9 @@ export async function listExchanges( exchangeRec.baseUrl, ); const opRetryRecord = await tx.wtx.getOperationRetry(taskId); - let reserveRec: ReserveRecord | undefined = undefined; + let reserveRec: WalletReserve | undefined = undefined; if (exchangeRec.currentMergeReserveRowId != null) { - reserveRec = await tx.reserves.get( + reserveRec = await tx.wtx.getReserve( exchangeRec.currentMergeReserveRowId, ); checkDbInvariant(!!reserveRec, "reserve record not found"); @@ -3490,9 +3490,9 @@ export async function checkIncomingAmountLegalUnderKycBalanceThreshold( // Check if we already have KYC for a sufficient threshold. const reserveId = exchangeRec.currentMergeReserveRowId; - let reserveRec: ReserveRecord | undefined; + let reserveRec: WalletReserve | undefined; if (reserveId) { - reserveRec = await tx.reserves.get(reserveId); + reserveRec = await tx.wtx.getReserve(reserveId); checkDbInvariant(!!reserveRec, "reserve"); // FIXME: also consider KYC expiration! if (reserveRec.thresholdNext) { @@ -3590,7 +3590,7 @@ export async function waitExchangeWalletKyc( logger.warn("KYC does not exist yet"); return false; } - const reserve = await tx.reserves.get(reserveId); + const reserve = await tx.wtx.getReserve(reserveId); if (!reserve) { throw Error("reserve not found"); } @@ -3687,16 +3687,14 @@ export async function handleStartExchangeWalletKyc( const oldExchangeState = getExchangeState(exchange); let mergeReserveRowId = exchange.currentMergeReserveRowId; if (mergeReserveRowId == null) { - const putRes = await tx.reserves.put({ + mergeReserveRowId = await tx.wtx.upsertReserve({ reservePriv: newReservePair.priv, reservePub: newReservePair.pub, }); - checkDbInvariant(typeof putRes.key === "number", "primary key type"); - mergeReserveRowId = putRes.key; exchange.currentMergeReserveRowId = mergeReserveRowId; await tx.exchanges.put(exchange); } - const reserveRec = await tx.reserves.get(mergeReserveRowId); + const reserveRec = await tx.wtx.getReserve(mergeReserveRowId); checkDbInvariant(reserveRec != null, "reserve record exists"); if ( reserveRec.thresholdGranted == null || @@ -3708,7 +3706,7 @@ export async function handleStartExchangeWalletKyc( ) { reserveRec.thresholdRequested = req.amount; reserveRec.status = ReserveRecordStatus.PendingLegiInit; - await tx.reserves.put(reserveRec); + await tx.wtx.upsertReserve(reserveRec); tx.notify({ type: NotificationType.ExchangeStateTransition, exchangeBaseUrl: exchange.baseUrl, @@ -3741,7 +3739,7 @@ export async function handleStartExchangeWalletKyc( async function handleExchangeKycPendingWallet( wex: WalletExecutionContext, exchange: ExchangeEntryRecord, - reserve: ReserveRecord, + reserve: WalletReserve, ): Promise<TaskRunResult> { checkDbInvariant(!!reserve.thresholdRequested, "threshold"); const threshold = reserve.thresholdRequested; @@ -3816,7 +3814,7 @@ async function handleExchangeKycSuccess( if (reserveId == null) { throw Error("expected exchange to have reserve ID"); } - const reserve = await tx.reserves.get(reserveId); + const reserve = await tx.wtx.getReserve(reserveId); checkDbInvariant(!!reserve, "merge reserve should exist"); switch (reserve.status) { case ReserveRecordStatus.PendingLegiInit: @@ -3834,7 +3832,7 @@ async function handleExchangeKycSuccess( reserve.thresholdNext = Amounts.stringify(nextThreshold); } - await tx.reserves.put(reserve); + await tx.wtx.upsertReserve(reserve); logger.info(`newly granted threshold: ${reserve.thresholdGranted}`); tx.notify({ type: NotificationType.ExchangeStateTransition, @@ -3869,7 +3867,7 @@ function findNextBalanceLimit( async function handleExchangeKycRespLegi( wex: WalletExecutionContext, exchangeBaseUrl: string, - reserve: ReserveRecord, + reserve: WalletReserve, kycBody: LegitimizationNeededResponse, ): Promise<TaskRunResult> { const sigResp = await wex.cryptoApi.signWalletKycAuth({ @@ -3930,7 +3928,7 @@ async function handleExchangeKycRespLegi( if (reserveId == null) { throw Error("expected exchange to have reserve ID"); } - const reserve = await tx.reserves.get(reserveId); + const reserve = await tx.wtx.getReserve(reserveId); checkDbInvariant(!!reserve, "merge reserve should exist"); switch (reserve.status) { case ReserveRecordStatus.PendingLegiInit: @@ -3943,7 +3941,7 @@ async function handleExchangeKycRespLegi( reserve.amlReview = accountKycStatusResp.aml_review; reserve.kycAccessToken = accountKycStatusResp.access_token; - await tx.reserves.put(reserve); + await tx.wtx.upsertReserve(reserve); tx.notify({ type: NotificationType.ExchangeStateTransition, exchangeBaseUrl: exchange.baseUrl, @@ -3963,7 +3961,7 @@ async function handleExchangeKycRespLegi( async function handleExchangeKycPendingLegitimization( wex: WalletExecutionContext, exchange: ExchangeEntryRecord, - reserve: ReserveRecord, + reserve: WalletReserve, ): Promise<TaskRunResult> { // FIXME: Cache this signature const sigResp = await wex.cryptoApi.signWalletKycAuth({ @@ -4035,9 +4033,9 @@ export async function processExchangeKyc( return undefined; } const reserveId = exchange.currentMergeReserveRowId; - let reserve: ReserveRecord | undefined = undefined; + let reserve: WalletReserve | undefined = undefined; if (reserveId != null) { - reserve = await tx.reserves.get(reserveId); + reserve = await tx.wtx.getReserve(reserveId); } return { exchange, reserve }; }); @@ -4243,7 +4241,7 @@ export async function migrateExchange( .iter(req.oldExchangeBaseUrl) .forEachAsync(async (rec) => { rec.exchangeBaseUrl = req.newExchangeBaseUrl; - await tx.recoupGroups.put(rec); + await tx.wtx.upsertRecoupGroup(rec); }); } diff --git a/packages/taler-wallet-core/src/pay-peer-common.ts b/packages/taler-wallet-core/src/pay-peer-common.ts @@ -23,10 +23,10 @@ import { TalerProtocolTimestamp, checkDbInvariant, } from "@gnu-taler/taler-util"; +import { WalletReserve } from "./db-common.js"; import { SpendCoinDetails } from "./crypto/cryptoImplementation.js"; import { DbPeerPushPaymentCoinSelection, - ReserveRecord, } from "./db-indexeddb.js"; import { getTotalRefreshCost } from "./refresh.js"; import { @@ -127,33 +127,28 @@ export async function getMergeReserveInfo( req: { exchangeBaseUrl: string; }, -): Promise<ReserveRecord> { +): Promise<WalletReserve> { // We have to eagerly create the key pair outside of the transaction, // due to the async crypto API. const newReservePair = await wex.cryptoApi.createEddsaKeypair({}); - const mergeReserveRecord: ReserveRecord = await wex.runLegacyWalletDbTx( + const mergeReserveRecord: WalletReserve = await wex.runLegacyWalletDbTx( async (tx) => { const ex = await tx.exchanges.get(req.exchangeBaseUrl); checkDbInvariant(!!ex, `no exchange record for ${req.exchangeBaseUrl}`); if (ex.currentMergeReserveRowId != null) { - const reserve = await tx.reserves.get(ex.currentMergeReserveRowId); + const reserve = await tx.wtx.getReserve(ex.currentMergeReserveRowId); checkDbInvariant( !!reserve, `reserver ${ex.currentMergeReserveRowId} missing in db`, ); return reserve; } - const reserve: ReserveRecord = { + const reserve: WalletReserve = { reservePriv: newReservePair.priv, reservePub: newReservePair.pub, }; - const insertResp = await tx.reserves.put(reserve); - checkDbInvariant( - typeof insertResp.key === "number", - `reserve key is not a number`, - ); - reserve.rowId = insertResp.key; + reserve.rowId = await tx.wtx.upsertReserve(reserve); ex.currentMergeReserveRowId = reserve.rowId; await tx.exchanges.put(ex); return reserve; diff --git a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts @@ -550,7 +550,7 @@ async function processPendingReady( } const reserve = await wex.runLegacyWalletDbTx((tx) => - tx.reserves.get(pullIni.mergeReserveRowId), + tx.wtx.getReserve(pullIni.mergeReserveRowId), ); if (!reserve) { @@ -790,7 +790,7 @@ async function processPeerPullCreditCreatePurse( const purseFee = Amounts.stringify(Amounts.zeroOfAmount(pullIni.amount)); const mergeReserve = await wex.runLegacyWalletDbTx(async (tx) => - tx.reserves.get(pullIni.mergeReserveRowId), + tx.wtx.getReserve(pullIni.mergeReserveRowId), ); if (!mergeReserve) { throw Error("merge reserve for peer pull payment not found in database"); diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts @@ -58,10 +58,10 @@ import { WalletCoin, WalletRefreshCoinSource, WalletWithdrawCoinSource, + WalletRecoupGroup, } from "./db-common.js"; import { CoinSourceType, - RecoupGroupRecord, WithdrawalRecordType, } from "./db-indexeddb.js"; import { createRefreshGroup } from "./refresh.js"; @@ -82,7 +82,7 @@ const logger = new Logger("operations/recoup.ts"); export async function putGroupAsFinished( wex: WalletExecutionContext, tx: LegacyWalletTxHandle, - recoupGroup: RecoupGroupRecord, + recoupGroup: WalletRecoupGroup, coinIdx: number, ): Promise<void> { const ctx = new RecoupTransactionContext(wex, recoupGroup.recoupGroupId); @@ -93,7 +93,7 @@ export async function putGroupAsFinished( return; } recoupGroup.recoupFinishedPerCoin[coinIdx] = true; - await tx.recoupGroups.put(recoupGroup); + await tx.wtx.upsertRecoupGroup(recoupGroup); await ctx.updateTransactionMeta(tx); } @@ -107,7 +107,7 @@ async function recoupRewardCoin( // Thus we just put the coin to sleep. // FIXME: somehow report this to the user await wex.runLegacyWalletDbTx(async (tx) => { - const recoupGroup = await tx.recoupGroups.get(recoupGroupId); + const recoupGroup = await tx.wtx.getRecoupGroup(recoupGroupId); if (!recoupGroup) { return; } @@ -170,7 +170,7 @@ async function recoupRefreshCoin( } await wex.runLegacyWalletDbTx(async (tx) => { - const recoupGroup = await tx.recoupGroups.get(recoupGroupId); + const recoupGroup = await tx.wtx.getRecoupGroup(recoupGroupId); if (!recoupGroup) { return; } @@ -268,7 +268,7 @@ export async function recoupWithdrawCoin( // FIXME: verify that our expectations about the amount match await wex.runLegacyWalletDbTx(async (tx) => { - const recoupGroup = await tx.recoupGroups.get(recoupGroupId); + const recoupGroup = await tx.wtx.getRecoupGroup(recoupGroupId); if (!recoupGroup) { return; } @@ -294,7 +294,7 @@ export async function processRecoupGroup( } let recoupGroup = await wex.runLegacyWalletDbTx(async (tx) => { - return tx.recoupGroups.get(recoupGroupId); + return tx.wtx.getRecoupGroup(recoupGroupId); }); if (!recoupGroup) { return TaskRunResult.finished(); @@ -314,7 +314,7 @@ export async function processRecoupGroup( await Promise.all(ps); recoupGroup = await wex.runLegacyWalletDbTx(async (tx) => { - return tx.recoupGroups.get(recoupGroupId); + return tx.wtx.getRecoupGroup(recoupGroupId); }); if (!recoupGroup) { return TaskRunResult.finished(); @@ -338,7 +338,7 @@ export async function processRecoupGroup( throw Error(`Coin ${coinPub} not found, can't request recoup`); } if (coin.coinSource.type === CoinSourceType.Withdraw) { - const reserve = await tx.reserves.indexes.byReservePub.get( + const reserve = await tx.wtx.getReserveByReservePub( coin.coinSource.reservePub, ); if (!reserve) { @@ -380,7 +380,7 @@ export async function processRecoupGroup( const ctx = new RecoupTransactionContext(wex, recoupGroupId); await wex.runLegacyWalletDbTx(async (tx) => { - const rg2 = await tx.recoupGroups.get(recoupGroupId); + const rg2 = await tx.wtx.getRecoupGroup(recoupGroupId); if (!rg2) { return; } @@ -399,7 +399,7 @@ export async function processRecoupGroup( }), ); } - await tx.recoupGroups.put(rg2); + await tx.wtx.upsertRecoupGroup(rg2); await ctx.updateTransactionMeta(tx); }); return TaskRunResult.finished(); @@ -424,7 +424,7 @@ export class RecoupTransactionContext implements TransactionContext { } async updateTransactionMeta(tx: LegacyWalletTxHandle): Promise<void> { - const recoupRec = await tx.recoupGroups.get(this.recoupGroupId); + const recoupRec = await tx.wtx.getRecoupGroup(this.recoupGroupId); if (!recoupRec) { await tx.wtx.deleteTransactionMeta(this.transactionId); return; @@ -480,11 +480,11 @@ export class RecoupTransactionContext implements TransactionContext { tx: LegacyWalletTxHandle, ): Promise<{ notifs: WalletNotification[] }> { const notifs: WalletNotification[] = []; - const rec = await tx.recoupGroups.get(this.recoupGroupId); + const rec = await tx.wtx.getRecoupGroup(this.recoupGroupId); if (!rec) { return { notifs }; } - await tx.recoupGroups.delete(this.recoupGroupId); + await tx.wtx.deleteRecoupGroup(this.recoupGroupId); await this.updateTransactionMeta(tx); return { notifs }; } @@ -505,7 +505,7 @@ export async function createRecoupGroup( const recoupGroupId = encodeCrock(getRandomBytes(32)); const ctx = new RecoupTransactionContext(wex, recoupGroupId); - const recoupGroup: RecoupGroupRecord = { + const recoupGroup: WalletRecoupGroup = { recoupGroupId, exchangeBaseUrl: exchangeBaseUrl, coinPubs: coinPubs, @@ -526,7 +526,7 @@ export async function createRecoupGroup( await tx.coins.put(coin); } - await tx.recoupGroups.put(recoupGroup); + await tx.wtx.upsertRecoupGroup(recoupGroup); await ctx.updateTransactionMeta(tx); wex.taskScheduler.startShepherdTask(ctx.taskId); @@ -543,7 +543,7 @@ async function processRecoupForCoin( coinIdx: number, ): Promise<void> { const coin = await wex.runLegacyWalletDbTx(async (tx) => { - const recoupGroup = await tx.recoupGroups.get(recoupGroupId); + const recoupGroup = await tx.wtx.getRecoupGroup(recoupGroupId); if (!recoupGroup) { return; } diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -1259,7 +1259,7 @@ async function handleTestingGetReserveHistory( req: TestingGetReserveHistoryRequest, ): Promise<any> { const reserve = await wex.runLegacyWalletDbTx(async (tx) => { - return tx.reserves.indexes.byReservePub.get(req.reservePub); + return tx.wtx.getReserveByReservePub(req.reservePub); }); if (!reserve) { throw Error("no reserve pub found"); diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -3609,7 +3609,7 @@ export async function internalPerformCreateWithdrawalGroup( }; } await tx.withdrawalGroups.add(withdrawalGroup); - await tx.reserves.put({ + await tx.wtx.upsertReserve({ reservePub: withdrawalGroup.reservePub, reservePriv: withdrawalGroup.reservePriv, });