commit 30d82873dbb6deb305797d758a8238af0e06206d parent e5673419eb668491568075f06590a357a174bb0a Author: Florian Dold <dold@taler.net> Date: Sat, 18 Jul 2026 21:11:09 +0200 db: add withdrawal group and planchet accessors Diffstat:
14 files changed, 521 insertions(+), 384 deletions(-)
diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts @@ -90,10 +90,10 @@ import { RefreshOperationStatus, WithdrawalGroupStatus, WalletRefreshGroup, + WithdrawalRecordType, } from "./db-common.js"; import { DonationSummaryRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { WalletDbTransaction } from "./dbtx.js"; import { diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts @@ -71,6 +71,7 @@ import { WalletDepositGroup, WalletRecoupGroup, WalletRefreshGroup, + WalletWithdrawalGroup, } from "./db-common.js"; import { ExchangeEntryRecord, @@ -79,7 +80,6 @@ import { PeerPushCreditRecord, PeerPushDebitRecord, PurchaseRecord, - WithdrawalGroupRecord, } from "./db-indexeddb.js"; import { WalletDbTransaction } from "./dbtx.js"; import { ReadyExchangeSummary } from "./exchanges.js"; @@ -801,7 +801,7 @@ export function constructTaskIdentifier(p: ParsedTaskIdentifier): TaskIdStr { } export namespace TaskIdentifiers { - export function forWithdrawal(wg: WithdrawalGroupRecord): TaskIdStr { + export function forWithdrawal(wg: WalletWithdrawalGroup): TaskIdStr { return `${PendingTaskType.Withdraw}:${wg.withdrawalGroupId}` as TaskIdStr; } export function forExchangeUpdate(exch: ExchangeEntryRecord): TaskIdStr { diff --git a/packages/taler-wallet-core/src/db-common.ts b/packages/taler-wallet-core/src/db-common.ts @@ -33,6 +33,10 @@ import { CoinRefreshRequest, ExchangeRefundRequest, RefreshReason, + WithdrawalExchangeAccountDetails, + CoinEnvelope, + TalerProtocolDuration, + DenomSelectionState, CoinStatus, AgeCommitmentProof, TransactionIdStr, @@ -503,6 +507,277 @@ export interface WalletRefreshSession { // (legacy v1 refresh) } +export const enum WithdrawalRecordType { + BankManual = "bank-manual", + BankIntegrated = "bank-integrated", + PeerPullCredit = "peer-pull-credit", + PeerPushCredit = "peer-push-credit", + Recoup = "recoup", +} + +/** + * Extra info about a withdrawal that is used + * with a bank-integrated withdrawal. + */ +export interface ReserveBankInfo { + talerWithdrawUri: string; + + /** + * URL that the user can be redirected to, and allows + * them to confirm (or abort) the bank-integrated withdrawal. + */ + confirmUrl: string | undefined; + + /** + * Exchange payto URI that the bank will use to fund the reserve. + */ + exchangePaytoUri?: string; + + /** + * Time when the information about this reserve was posted to the bank. + * + * Only applies if bankWithdrawStatusUrl is defined. + * + * Set to undefined if that hasn't happened yet. + */ + timestampReserveInfoPosted: DbPreciseTimestamp | undefined; + + /** + * Time when the reserve was confirmed by the bank. + * + * Set to undefined if not confirmed yet. + */ + timestampBankConfirmed: DbPreciseTimestamp | undefined; + + wireTypes: string[] | undefined; + + currency: string | undefined; + + externalConfirmation?: boolean; + + senderWire?: string; +} + +export interface WgInfoBankIntegrated { + withdrawalType: WithdrawalRecordType.BankIntegrated; + + /** + * Extra state for when this is a withdrawal involving + * a Taler-integrated bank. + */ + bankInfo: ReserveBankInfo; + + /** + * Info about withdrawal accounts, possibly including currency conversion. + */ + exchangeCreditAccounts?: WithdrawalExchangeAccountDetails[]; +} + +export interface WgInfoBankManual { + withdrawalType: WithdrawalRecordType.BankManual; + + /** + * Info about withdrawal accounts, possibly including currency conversion. + */ + exchangeCreditAccounts?: WithdrawalExchangeAccountDetails[]; +} + +export interface WgInfoBankPeerPull { + withdrawalType: WithdrawalRecordType.PeerPullCredit; + + // FIXME: include a transaction ID here? + + /** + * Needed to quickly construct the taler:// URI for the counterparty + * without a join. + */ + contractPriv: string; +} + +export interface WgInfoBankPeerPush { + withdrawalType: WithdrawalRecordType.PeerPushCredit; + + // FIXME: include a transaction ID here? +} + +export interface WgInfoBankRecoup { + withdrawalType: WithdrawalRecordType.Recoup; +} + +export type WgInfo = + | WgInfoBankIntegrated + | WgInfoBankManual + | WgInfoBankPeerPull + | WgInfoBankPeerPush + | WgInfoBankRecoup; + +/** + * Group of withdrawal operations that need to be executed. + * (Either for a normal withdrawal or from a reward.) + * + * The withdrawal group record is only created after we know + * the coin selection we want to withdraw. + */ +export interface WalletWithdrawalGroup { + /** + * Unique identifier for the withdrawal group. + */ + withdrawalGroupId: string; + + wgInfo: WgInfo; + + /** + * If set to true, the account used during withdrawal is treated as an + * account that does not belong to the user. It won't be shown in + * the list of know bank accounts. + * + * Defaults to false. + */ + isForeignAccount?: boolean; + + kycPaytoHash?: string; + + kycAccessToken?: string; + + kycLastCheckStatus?: number | undefined; + kycLastCheckCode?: number | undefined; + kycLastRuleGen?: number | undefined; + kycLastAmlReview?: boolean | undefined; + kycLastDeny?: DbPreciseTimestamp | undefined; + + /** + * Delay to wait until the next withdrawal attempt. + * + * @deprecated by https://bugs.gnunet.org/view.php?id=9694 + */ + kycWithdrawalDelay?: TalerProtocolDuration; + + /** + * Secret seed used to derive planchets. + * Stored since planchets are created lazily. + */ + secretSeed: string; + + /** + * Public key of the reserve that we're withdrawing from. + */ + reservePub: string; + + /** + * The reserve private key. + * + * FIXME: Already in the reserves object store, redundant! + */ + reservePriv: string; + + /** + * The exchange base URL that we're withdrawing from. + * (Redundantly stored, as the reserve record also has this info.) + */ + exchangeBaseUrl?: string; + + /** + * When was the withdrawal operation started started? + * Timestamp in milliseconds. + */ + timestampStart: DbPreciseTimestamp; + + /** + * When was the withdrawal operation completed? + */ + timestampFinish?: DbPreciseTimestamp; + + /** + * Current status of the reserve. + */ + status: WithdrawalGroupStatus; + + /** + * Restrict withdrawals from this reserve to this age. + */ + restrictAge?: number; + + /** + * Amount that was sent by the user to fund the reserve. + */ + instructedAmount?: AmountString; + + /** + * Amount that was observed when querying the reserve that + * we are withdrawing from. + * + * Useful for diagnostics. + */ + reserveBalanceAmount?: AmountString; + + /** + * Amount including fees (i.e. the amount subtracted from the + * reserve to withdraw all coins in this withdrawal session). + * + * (Initial amount confirmed by the user, might differ with denomSel + * on reselection.) + */ + rawWithdrawalAmount?: AmountString; + + /** + * Amount that will be added to the balance when the withdrawal succeeds. + * + * (Initial amount confirmed by the user, might differ with denomSel + * on reselection.) + */ + effectiveWithdrawalAmount?: AmountString; + + /** + * Denominations selected for withdrawal. + */ + denomsSel?: DenomSelectionState; + + abortReason?: TalerErrorDetail; + failReason?: TalerErrorDetail; +} + +/** + * A coin that isn't yet signed by an exchange. + */ +export interface WalletPlanchet { + /** + * Public key of the coin. + */ + coinPub: string; + + /** + * Private key of the coin. + */ + coinPriv: string; + + /** + * Withdrawal group that this planchet belongs to + * (or the empty string). + */ + withdrawalGroupId: string; + + /** + * Index within the withdrawal group (or -1). + */ + coinIdx: number; + + planchetStatus: PlanchetStatus; + + lastError: TalerErrorDetail | undefined; + + denomPubHash: string; + + blindingKey: string; + + withdrawSig: string; + + coinEv: CoinEnvelope; + + coinEvHash: string; + + ageCommitmentProof?: AgeCommitmentProof; +} + 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 @@ -123,6 +123,16 @@ import { WalletDepositInfoPerExchange, WalletRecoupGroup, WalletRefreshGroup, + WithdrawalRecordType, + ReserveBankInfo, + WgInfo, + WgInfoBankIntegrated, + WgInfoBankManual, + WgInfoBankPeerPull, + WgInfoBankPeerPush, + WgInfoBankRecoup, + WalletWithdrawalGroup, + WalletPlanchet, WalletRefreshSession, WalletRefreshGroupPerExchangeInfo, WalletReserve, @@ -238,49 +248,6 @@ export interface DenomFamilyParams { feeRefund: AmountString; } -/** - * Extra info about a withdrawal that is used - * with a bank-integrated withdrawal. - */ -export interface ReserveBankInfo { - talerWithdrawUri: string; - - /** - * URL that the user can be redirected to, and allows - * them to confirm (or abort) the bank-integrated withdrawal. - */ - confirmUrl: string | undefined; - - /** - * Exchange payto URI that the bank will use to fund the reserve. - */ - exchangePaytoUri?: string; - - /** - * Time when the information about this reserve was posted to the bank. - * - * Only applies if bankWithdrawStatusUrl is defined. - * - * Set to undefined if that hasn't happened yet. - */ - timestampReserveInfoPosted: DbPreciseTimestamp | undefined; - - /** - * Time when the reserve was confirmed by the bank. - * - * Set to undefined if not confirmed yet. - */ - timestampBankConfirmed: DbPreciseTimestamp | undefined; - - wireTypes: string[] | undefined; - - currency: string | undefined; - - externalConfirmation?: boolean; - - senderWire?: string; -} - export interface DenominationFamilyRecord { denominationFamilySerial?: number; familyParams: DenomFamilyParams; @@ -506,48 +473,6 @@ export interface ExchangeEntryRecord { } /** - * A coin that isn't yet signed by an exchange. - */ -export interface PlanchetRecord { - /** - * Public key of the coin. - */ - coinPub: string; - - /** - * Private key of the coin. - */ - coinPriv: string; - - /** - * Withdrawal group that this planchet belongs to - * (or the empty string). - */ - withdrawalGroupId: string; - - /** - * Index within the withdrawal group (or -1). - */ - coinIdx: number; - - planchetStatus: PlanchetStatus; - - lastError: TalerErrorDetail | undefined; - - denomPubHash: string; - - blindingKey: string; - - withdrawSig: string; - - coinEv: CoinEnvelope; - - coinEvHash: string; - - ageCommitmentProof?: AgeCommitmentProof; -} - -/** * Object to be hashed for use as a grouping key for token listings, such that * any change in token family details results in a separate list item. */ @@ -915,194 +840,8 @@ export interface PurchaseRecord { } // FIXME: Should these be numeric codes? -export const enum WithdrawalRecordType { - BankManual = "bank-manual", - BankIntegrated = "bank-integrated", - PeerPullCredit = "peer-pull-credit", - PeerPushCredit = "peer-push-credit", - Recoup = "recoup", -} - -export interface WgInfoBankIntegrated { - withdrawalType: WithdrawalRecordType.BankIntegrated; - - /** - * Extra state for when this is a withdrawal involving - * a Taler-integrated bank. - */ - bankInfo: ReserveBankInfo; - - /** - * Info about withdrawal accounts, possibly including currency conversion. - */ - exchangeCreditAccounts?: WithdrawalExchangeAccountDetails[]; -} - -export interface WgInfoBankManual { - withdrawalType: WithdrawalRecordType.BankManual; - - /** - * Info about withdrawal accounts, possibly including currency conversion. - */ - exchangeCreditAccounts?: WithdrawalExchangeAccountDetails[]; -} - -export interface WgInfoBankPeerPull { - withdrawalType: WithdrawalRecordType.PeerPullCredit; - - // FIXME: include a transaction ID here? - - /** - * Needed to quickly construct the taler:// URI for the counterparty - * without a join. - */ - contractPriv: string; -} - -export interface WgInfoBankPeerPush { - withdrawalType: WithdrawalRecordType.PeerPushCredit; - - // FIXME: include a transaction ID here? -} - -export interface WgInfoBankRecoup { - withdrawalType: WithdrawalRecordType.Recoup; -} - -export type WgInfo = - | WgInfoBankIntegrated - | WgInfoBankManual - | WgInfoBankPeerPull - | WgInfoBankPeerPush - | WgInfoBankRecoup; - export type KycUserType = "individual" | "business"; -/** - * Group of withdrawal operations that need to be executed. - * (Either for a normal withdrawal or from a reward.) - * - * The withdrawal group record is only created after we know - * the coin selection we want to withdraw. - */ -export interface WithdrawalGroupRecord { - /** - * Unique identifier for the withdrawal group. - */ - withdrawalGroupId: string; - - wgInfo: WgInfo; - - /** - * If set to true, the account used during withdrawal is treated as an - * account that does not belong to the user. It won't be shown in - * the list of know bank accounts. - * - * Defaults to false. - */ - isForeignAccount?: boolean; - - kycPaytoHash?: string; - - kycAccessToken?: string; - - kycLastCheckStatus?: number | undefined; - kycLastCheckCode?: number | undefined; - kycLastRuleGen?: number | undefined; - kycLastAmlReview?: boolean | undefined; - kycLastDeny?: DbPreciseTimestamp | undefined; - - /** - * Delay to wait until the next withdrawal attempt. - * - * @deprecated by https://bugs.gnunet.org/view.php?id=9694 - */ - kycWithdrawalDelay?: TalerProtocolDuration; - - /** - * Secret seed used to derive planchets. - * Stored since planchets are created lazily. - */ - secretSeed: string; - - /** - * Public key of the reserve that we're withdrawing from. - */ - reservePub: string; - - /** - * The reserve private key. - * - * FIXME: Already in the reserves object store, redundant! - */ - reservePriv: string; - - /** - * The exchange base URL that we're withdrawing from. - * (Redundantly stored, as the reserve record also has this info.) - */ - exchangeBaseUrl?: string; - - /** - * When was the withdrawal operation started started? - * Timestamp in milliseconds. - */ - timestampStart: DbPreciseTimestamp; - - /** - * When was the withdrawal operation completed? - */ - timestampFinish?: DbPreciseTimestamp; - - /** - * Current status of the reserve. - */ - status: WithdrawalGroupStatus; - - /** - * Restrict withdrawals from this reserve to this age. - */ - restrictAge?: number; - - /** - * Amount that was sent by the user to fund the reserve. - */ - instructedAmount?: AmountString; - - /** - * Amount that was observed when querying the reserve that - * we are withdrawing from. - * - * Useful for diagnostics. - */ - reserveBalanceAmount?: AmountString; - - /** - * Amount including fees (i.e. the amount subtracted from the - * reserve to withdraw all coins in this withdrawal session). - * - * (Initial amount confirmed by the user, might differ with denomSel - * on reselection.) - */ - rawWithdrawalAmount?: AmountString; - - /** - * Amount that will be added to the balance when the withdrawal succeeds. - * - * (Initial amount confirmed by the user, might differ with denomSel - * on reselection.) - */ - effectiveWithdrawalAmount?: AmountString; - - /** - * Denominations selected for withdrawal. - */ - denomsSel?: DenomSelectionState; - - abortReason?: TalerErrorDetail; - failReason?: TalerErrorDetail; -} - export interface BankWithdrawUriRecord { /** * The withdraw URI we got from the bank. @@ -2013,7 +1752,7 @@ export const WalletIndexedDbStoresV1 = { }), withdrawalGroups: describeStore( "withdrawalGroups", - describeContents<WithdrawalGroupRecord>({ + describeContents<WalletWithdrawalGroup>({ keyPath: "withdrawalGroupId", }), { @@ -2029,7 +1768,7 @@ export const WalletIndexedDbStoresV1 = { ), planchets: describeStore( "planchets", - describeContents<PlanchetRecord>({ keyPath: "coinPub" }), + describeContents<WalletPlanchet>({ keyPath: "coinPub" }), { byGroupAndIndex: describeIndex( "byGroupAndIndex", diff --git a/packages/taler-wallet-core/src/dbtx-indexeddb.ts b/packages/taler-wallet-core/src/dbtx-indexeddb.ts @@ -59,10 +59,11 @@ import { WalletReserve, WalletRefreshGroup, WalletRefreshSession, + WalletWithdrawalGroup, + WalletPlanchet, } from "./db-common.js"; import type { ExchangeEntryRecord, - WithdrawalGroupRecord, ExchangeDetailsRecord, DonationSummaryRecord, } from "./db-indexeddb.js"; @@ -269,6 +270,90 @@ export class IdbWalletTransaction implements WalletDbTransaction { }); } + async getWithdrawalGroup( + withdrawalGroupId: string, + ): Promise<WalletWithdrawalGroup | undefined> { + const tx = this.tx; + return await tx.withdrawalGroups.get(withdrawalGroupId); + } + + async upsertWithdrawalGroup(rec: WalletWithdrawalGroup): Promise<void> { + const tx = this.tx; + await tx.withdrawalGroups.put(rec); + } + + async deleteWithdrawalGroup(withdrawalGroupId: string): Promise<void> { + const tx = this.tx; + await tx.withdrawalGroups.delete(withdrawalGroupId); + } + + async getWithdrawalGroupByTalerWithdrawUri( + talerWithdrawUri: string, + ): Promise<WalletWithdrawalGroup | undefined> { + const tx = this.tx; + return await tx.withdrawalGroups.indexes.byTalerWithdrawUri.get( + talerWithdrawUri, + ); + } + + async getWithdrawalGroupsByExchange( + exchangeBaseUrl: string, + ): Promise<WalletWithdrawalGroup[]> { + const tx = this.tx; + return await tx.withdrawalGroups.indexes.byExchangeBaseUrl.getAll( + exchangeBaseUrl, + ); + } + + async getPlanchetByGroupAndIndex( + withdrawalGroupId: string, + coinIdx: number, + ): Promise<WalletPlanchet | undefined> { + const tx = this.tx; + return await tx.planchets.indexes.byGroupAndIndex.get([ + withdrawalGroupId, + coinIdx, + ]); + } + + async getPlanchet(coinPub: string): Promise<WalletPlanchet | undefined> { + const tx = this.tx; + return await tx.planchets.get(coinPub); + } + + async upsertPlanchet(rec: WalletPlanchet): Promise<void> { + const tx = this.tx; + await tx.planchets.put(rec); + } + + async deletePlanchet(coinPub: string): Promise<void> { + const tx = this.tx; + await tx.planchets.delete(coinPub); + } + + async getPlanchetsByGroup( + withdrawalGroupId: string, + ): Promise<WalletPlanchet[]> { + const tx = this.tx; + return await tx.planchets.indexes.byGroup.getAll(withdrawalGroupId); + } + + async countPlanchetsByGroup(withdrawalGroupId: string): Promise<number> { + const tx = this.tx; + const keys = + await tx.planchets.indexes.byGroup.getAllKeys(withdrawalGroupId); + return keys.length; + } + + async deletePlanchetsByGroup(withdrawalGroupId: string): Promise<void> { + const tx = this.tx; + const planchets = + await tx.planchets.indexes.byGroup.getAll(withdrawalGroupId); + for (const p of planchets) { + await tx.planchets.delete(p.coinPub); + } + } + async getRefreshGroup( refreshGroupId: string, ): Promise<WalletRefreshGroup | undefined> { @@ -824,7 +909,7 @@ export class IdbWalletTransaction implements WalletDbTransaction { ); } - async getActiveWithdrawalGroups(): Promise<WithdrawalGroupRecord[]> { + async getActiveWithdrawalGroups(): Promise<WalletWithdrawalGroup[]> { return await this.tx.withdrawalGroups.indexes.byStatus.getAll( getActiveKeyRange(), ); diff --git a/packages/taler-wallet-core/src/dbtx.ts b/packages/taler-wallet-core/src/dbtx.ts @@ -63,10 +63,11 @@ import { WalletReserve, WalletRefreshGroup, WalletRefreshSession, + WalletWithdrawalGroup, + WalletPlanchet, } from "./db-common.js"; import type { ExchangeEntryRecord, - WithdrawalGroupRecord, ExchangeDetailsRecord, DonationSummaryRecord, PurchaseRecord, @@ -177,6 +178,48 @@ export interface WalletDbTransaction { */ upsertContractTerms(rec: WalletContractTerms): Promise<void>; + getWithdrawalGroup( + withdrawalGroupId: string, + ): Promise<WalletWithdrawalGroup | undefined>; + + upsertWithdrawalGroup(rec: WalletWithdrawalGroup): Promise<void>; + + deleteWithdrawalGroup(withdrawalGroupId: string): Promise<void>; + + getWithdrawalGroupByTalerWithdrawUri( + talerWithdrawUri: string, + ): Promise<WalletWithdrawalGroup | undefined>; + + getWithdrawalGroupsByExchange( + exchangeBaseUrl: string, + ): Promise<WalletWithdrawalGroup[]>; + + /** + * Get a planchet by its withdrawal group and coin index. + */ + getPlanchetByGroupAndIndex( + withdrawalGroupId: string, + coinIdx: number, + ): Promise<WalletPlanchet | undefined>; + + /** + * Get a planchet by its coin public key, which is the primary key. + */ + getPlanchet(coinPub: string): Promise<WalletPlanchet | undefined>; + + upsertPlanchet(rec: WalletPlanchet): Promise<void>; + + deletePlanchet(coinPub: string): Promise<void>; + + getPlanchetsByGroup(withdrawalGroupId: string): Promise<WalletPlanchet[]>; + + countPlanchetsByGroup(withdrawalGroupId: string): Promise<number>; + + /** + * Delete every planchet belonging to a withdrawal group. + */ + deletePlanchetsByGroup(withdrawalGroupId: string): Promise<void>; + getRefreshGroup( refreshGroupId: string, ): Promise<WalletRefreshGroup | undefined>; @@ -393,7 +436,7 @@ export interface WalletDbTransaction { getActiveRefreshGroups(): Promise<WalletRefreshGroup[]>; - getActiveWithdrawalGroups(): Promise<WithdrawalGroupRecord[]>; + getActiveWithdrawalGroups(): Promise<WalletWithdrawalGroup[]>; getActivePeerPushDebits(): Promise<WalletPeerPushDebit[]>; diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts @@ -119,10 +119,10 @@ import { WalletDepositGroup, WalletDepositTrackingInfo, WalletDepositInfoPerExchange, + WalletWithdrawalGroup, + WithdrawalRecordType, } from "./db-common.js"; import { - WithdrawalGroupRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { ReadyExchangeSummary, @@ -1227,10 +1227,10 @@ async function tryFindAccountKeypair( let candidateTimestamp: AbsoluteTime | undefined = undefined; let candidateRes: EddsaKeyPairStrings | undefined = undefined; const allWithdrawalRecs = - await tx.withdrawalGroups.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); + await tx.wtx.getWithdrawalGroupsByExchange(exchangeBaseUrl); // We only consider withdrawals that were actual // withdrawals from a bank account. - const withdrawalRecs: WithdrawalGroupRecord[] = []; + const withdrawalRecs: WalletWithdrawalGroup[] = []; for (const rec of allWithdrawalRecs) { switch (rec.wgInfo.withdrawalType) { case WithdrawalRecordType.BankIntegrated: diff --git a/packages/taler-wallet-core/src/dev-experiments.ts b/packages/taler-wallet-core/src/dev-experiments.ts @@ -64,10 +64,10 @@ import { timestampPreciseToDb, timestampProtocolToDb, WalletRefreshGroup, + WithdrawalRecordType, } from "./db-common.js"; import { DenomLossEventRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { DenomLossTransactionContext, @@ -568,7 +568,7 @@ async function addFakeTx( timestamp = AbsoluteTime.now(); } await wex.runLegacyWalletDbTx(async (tx) => { - await tx.withdrawalGroups.add({ + await tx.wtx.upsertWithdrawalGroup({ reservePriv: reservePair.priv, reservePub: reservePair.pub, secretSeed, diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -3249,7 +3249,7 @@ async function purgeExchange( // transaction deletion was requested. { const withdrawalGroupRecs = - await tx.withdrawalGroups.indexes.byExchangeBaseUrl.getAll( + await tx.wtx.getWithdrawalGroupsByExchange( exchangeBaseUrl, ); for (const wg of withdrawalGroupRecs) { @@ -4338,7 +4338,7 @@ export async function migrateExchange( .iter(req.oldExchangeBaseUrl) .forEachAsync(async (rec) => { rec.exchangeBaseUrl = req.newExchangeBaseUrl; - await tx.withdrawalGroups.put(rec); + await tx.wtx.upsertWithdrawalGroup(rec); }); } diff --git a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts @@ -71,10 +71,10 @@ import { timestampPreciseFromDb, timestampPreciseToDb, WalletOperationRetry, + WalletWithdrawalGroup, + WithdrawalRecordType, } from "./db-common.js"; import { - WithdrawalGroupRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { BalanceThresholdCheckResult, @@ -176,10 +176,10 @@ export class PeerPullCreditTransactionContext implements TransactionContext { const peerContractTerms = ct.contractTermsRaw; - let wsr: WithdrawalGroupRecord | undefined = undefined; + let wsr: WalletWithdrawalGroup | undefined = undefined; let wsrOrt: WalletOperationRetry | undefined = undefined; if (pullCredit.withdrawalGroupId) { - wsr = await tx.withdrawalGroups.get(pullCredit.withdrawalGroupId); + wsr = await tx.wtx.getWithdrawalGroup(pullCredit.withdrawalGroupId); if (wsr) { const withdrawalOpId = TaskIdentifiers.forWithdrawal(wsr); wsrOrt = await tx.wtx.getOperationRetry(withdrawalOpId); @@ -710,7 +710,7 @@ async function processPeerPullCreditWithdrawing( if (rec?.status !== PeerPullPaymentCreditStatus.PendingWithdrawing) { return TaskRunResult.backoff(); } - const wg = await tx.withdrawalGroups.get(wgId); + const wg = await tx.wtx.getWithdrawalGroup(wgId); if (!wg) { // FIXME: Fail the operation instead? return TaskRunResult.backoff(); diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts @@ -73,11 +73,11 @@ import { timestampPreciseToDb, WalletPeerPushCredit, WalletOperationRetry, + WalletWithdrawalGroup, + WithdrawalRecordType, } from "./db-common.js"; import { WalletIndexedDbTransaction, - WithdrawalGroupRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { BalanceThresholdCheckResult, @@ -163,10 +163,10 @@ export class PeerPushCreditTransactionContext implements TransactionContext { return undefined; } - let wg: WithdrawalGroupRecord | undefined = undefined; + let wg: WalletWithdrawalGroup | undefined = undefined; let wgRetryRecord: WalletOperationRetry | undefined = undefined; if (pushInc.withdrawalGroupId) { - wg = await tx.withdrawalGroups.get(pushInc.withdrawalGroupId); + wg = await tx.wtx.getWithdrawalGroup(pushInc.withdrawalGroupId); if (wg) { const withdrawalOpId = TaskIdentifiers.forWithdrawal(wg); wgRetryRecord = await tx.wtx.getOperationRetry(withdrawalOpId); @@ -975,7 +975,7 @@ async function processPendingWithdrawing( if (ppi.status !== PeerPushCreditStatus.PendingWithdrawing) { return TaskRunResult.finished(); } - const wg = await tx.withdrawalGroups.get(wgId); + const wg = await tx.wtx.getWithdrawalGroup(wgId); if (!wg) { ppi.status = PeerPushCreditStatus.Failed; await h.update(ppi); diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts @@ -59,10 +59,10 @@ import { WalletRefreshCoinSource, WalletWithdrawCoinSource, WalletRecoupGroup, + WithdrawalRecordType, } from "./db-common.js"; import { CoinSourceType, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { createRefreshGroup } from "./refresh.js"; import { constructTransactionIdentifier } from "./transactions.js"; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -2124,7 +2124,7 @@ export async function handleTestingCorruptWithdrawalCoinSel( throw Error("expected withdrawal transaction ID"); } await wex.runLegacyWalletDbTx(async (tx) => { - const wg = await tx.withdrawalGroups.get(txId.withdrawalGroupId); + const wg = await tx.wtx.getWithdrawalGroup(txId.withdrawalGroupId); if (!wg) { return; } @@ -2132,7 +2132,7 @@ export async function handleTestingCorruptWithdrawalCoinSel( wg.denomsSel.selectedDenoms[0].denomPubHash = encodeCrock( getRandomBytes(64), ); - await tx.withdrawalGroups.put(wg); + await tx.wtx.upsertWithdrawalGroup(wg); } }); return {}; diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -147,13 +147,13 @@ import { WalletDenomination, WalletOperationRetry, WalletCoin, + WalletPlanchet, + WgInfo, + WalletWithdrawalGroup, + WithdrawalRecordType, } from "./db-common.js"; import { CoinSourceType, - PlanchetRecord, - WgInfo, - WithdrawalGroupRecord, - WithdrawalRecordType, } from "./db-indexeddb.js"; import { selectForcedWithdrawalDenominations, @@ -211,7 +211,7 @@ interface TxKycDetails { } function buildTransactionForBankIntegratedWithdraw( - wg: WithdrawalGroupRecord, + wg: WalletWithdrawalGroup, scopes: ScopeInfo[], ort: WalletOperationRetry | undefined, kycDetails: TxKycDetails | undefined, @@ -279,7 +279,7 @@ function buildTransactionForBankIntegratedWithdraw( } function buildTransactionForManualWithdraw( - wg: WithdrawalGroupRecord, + wg: WalletWithdrawalGroup, exchangeDetails: ExchangeDetails | undefined, scopes: ScopeInfo[], ort: WalletOperationRetry | undefined, @@ -371,7 +371,7 @@ export class WithdrawTransactionContext implements TransactionContext { async lookupFullTransaction( tx: LegacyWalletTxHandle, ): Promise<Transaction | undefined> { - const withdrawalGroupRecord = await tx.withdrawalGroups.get( + const withdrawalGroupRecord = await tx.wtx.getWithdrawalGroup( this.withdrawalGroupId, ); if (!withdrawalGroupRecord) { @@ -443,7 +443,7 @@ export class WithdrawTransactionContext implements TransactionContext { */ async updateTransactionMeta(tx: LegacyWalletTxHandle): Promise<void> { const ctx = this; - const wgRecord = await tx.withdrawalGroups.get(ctx.withdrawalGroupId); + const wgRecord = await tx.wtx.getWithdrawalGroup(ctx.withdrawalGroupId); if (!wgRecord) { await tx.wtx.deleteTransactionMeta(ctx.transactionId); return; @@ -488,16 +488,16 @@ export class WithdrawTransactionContext implements TransactionContext { async getRecordHandle( tx: LegacyWalletTxHandle, ): Promise< - [WithdrawalGroupRecord | undefined, RecordHandle<WithdrawalGroupRecord>] + [WalletWithdrawalGroup | undefined, RecordHandle<WalletWithdrawalGroup>] > { - return getGenericRecordHandle<WithdrawalGroupRecord>( + return getGenericRecordHandle<WalletWithdrawalGroup>( this, tx.wtx, - async () => tx.withdrawalGroups.get(this.withdrawalGroupId), + async () => tx.wtx.getWithdrawalGroup(this.withdrawalGroupId), async (r) => { - await tx.withdrawalGroups.put(r); + await tx.wtx.upsertWithdrawalGroup(r); }, - async () => tx.withdrawalGroups.delete(this.withdrawalGroupId), + async () => tx.wtx.deleteWithdrawalGroup(this.withdrawalGroupId), (r) => computeWithdrawalTransactionStatus(r), (r) => r.status, () => this.updateTransactionMeta(tx), @@ -515,11 +515,11 @@ export class WithdrawTransactionContext implements TransactionContext { if (!rec) { return; } - const planchets = await tx.planchets.indexes.byGroup.getAll( + const planchets = await tx.wtx.getPlanchetsByGroup( rec.withdrawalGroupId, ); for (const p of planchets) { - await tx.planchets.delete(p.coinPub); + await tx.wtx.deletePlanchet(p.coinPub); } await h.update(undefined); } @@ -688,7 +688,7 @@ export class WithdrawTransactionContext implements TransactionContext { * from the database's withdrawal group record. */ export function computeWithdrawalTransactionStatus( - wgRecord: WithdrawalGroupRecord, + wgRecord: WalletWithdrawalGroup, ): TransactionState { switch (wgRecord.status) { case WithdrawalGroupStatus.FailedBankAborted: @@ -852,7 +852,7 @@ export function computeWithdrawalTransactionStatus( * based on the database's withdrawal group record. */ export function computeWithdrawalTransactionActions( - wgRecord: WithdrawalGroupRecord, + wgRecord: WalletWithdrawalGroup, ): TransactionAction[] { switch (wgRecord.status) { case WithdrawalGroupStatus.FailedBankAborted: @@ -944,7 +944,7 @@ export function computeWithdrawalTransactionActions( async function processWithdrawalGroupRedenominate( ctx: WithdrawTransactionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { logger.trace("in processWithdrawalGroupRedenominate"); const wex = ctx.wex; @@ -976,7 +976,7 @@ async function processWithdrawalGroupRedenominate( async function processWithdrawalGroupBalanceKyc( ctx: WithdrawTransactionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { const exchangeBaseUrl = withdrawalGroup.exchangeBaseUrl; if (!withdrawalGroup.denomsSel) { @@ -1108,7 +1108,7 @@ async function transitionSimple( */ async function processWithdrawalGroupDialogProposed( ctx: WithdrawTransactionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { if ( withdrawalGroup.wgInfo.withdrawalType !== @@ -1366,7 +1366,7 @@ export async function getWithdrawableDenomsTx( */ async function processPlanchetGenerate( wex: WalletExecutionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, coinIdx: number, ): Promise<{ badDenom?: boolean }> { checkDbInvariant( @@ -1379,10 +1379,10 @@ async function processPlanchetGenerate( ); const exchangeBaseUrl = withdrawalGroup.exchangeBaseUrl; let planchet = await wex.runLegacyWalletDbTx(async (tx) => { - return tx.planchets.indexes.byGroupAndIndex.get([ + return tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); }); if (planchet) { return {}; @@ -1426,7 +1426,7 @@ async function processPlanchetGenerate( secretSeed: withdrawalGroup.secretSeed, restrictAge: withdrawalGroup.restrictAge, }); - const newPlanchet: PlanchetRecord = { + const newPlanchet: WalletPlanchet = { blindingKey: r.blindingKey, coinEv: r.coinEv, coinEvHash: r.coinEvHash, @@ -1441,15 +1441,15 @@ async function processPlanchetGenerate( lastError: undefined, }; await wex.runLegacyWalletDbTx(async (tx) => { - const p = await tx.planchets.indexes.byGroupAndIndex.get([ + const p = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (p) { planchet = p; return; } - await tx.planchets.put(newPlanchet); + await tx.wtx.upsertPlanchet(newPlanchet); planchet = newPlanchet; }); return {}; @@ -1472,7 +1472,7 @@ interface WithdrawalBatchResult { */ async function transitionKycRequired( wex: WalletExecutionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, resp: HttpResponse, startIdx: number, requestCoinIdxs: number[], @@ -1490,15 +1490,15 @@ async function transitionKycRequired( return; } for (let i = startIdx; i < requestCoinIdxs.length; i++) { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, requestCoinIdxs[i], - ]); + ); if (!planchet) { continue; } planchet.planchetStatus = PlanchetStatus.KycRequired; - await tx.planchets.put(planchet); + await tx.wtx.upsertPlanchet(planchet); } switch (wg2.status) { case WithdrawalGroupStatus.PendingReady: @@ -1524,7 +1524,7 @@ async function processPlanchetExchangeLegacyBatchRequest( wgContext: WithdrawalGroupStatusInfo, args: WithdrawalRequestBatchArgs, ): Promise<WithdrawalBatchResult> { - const withdrawalGroup: WithdrawalGroupRecord = wgContext.wgRecord; + const withdrawalGroup: WalletWithdrawalGroup = wgContext.wgRecord; logger.info( `processing planchet exchange batch request ${withdrawalGroup.withdrawalGroupId}, start=${args.coinStartIndex}, len=${args.batchSize}`, ); @@ -1545,10 +1545,10 @@ async function processPlanchetExchangeLegacyBatchRequest( coinIdx < wgContext.numPlanchets; coinIdx++ ) { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { continue; } @@ -1595,15 +1595,15 @@ async function processPlanchetExchangeLegacyBatchRequest( ): Promise<void> { logger.trace(`withdrawal request failed: ${j2s(errDetail)}`); await wex.runLegacyWalletDbTx(async (tx) => { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { return; } planchet.lastError = errDetail; - await tx.planchets.put(planchet); + await tx.wtx.upsertPlanchet(planchet); }); } @@ -1676,7 +1676,7 @@ async function processPlanchetExchangeBatchRequest( wgContext: WithdrawalGroupStatusInfo, args: WithdrawalRequestBatchArgs, ): Promise<WithdrawalBatchResult> { - const withdrawalGroup: WithdrawalGroupRecord = wgContext.wgRecord; + const withdrawalGroup: WalletWithdrawalGroup = wgContext.wgRecord; logger.info( `processing planchet exchange batch request ${withdrawalGroup.withdrawalGroupId}, start=${args.coinStartIndex}, len=${args.batchSize}`, ); @@ -1702,10 +1702,10 @@ async function processPlanchetExchangeBatchRequest( coinIdx < wgContext.numPlanchets; coinIdx++ ) { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { continue; } @@ -1749,15 +1749,15 @@ async function processPlanchetExchangeBatchRequest( ): Promise<void> { logger.trace(`withdrawal request failed: ${j2s(errDetail)}`); await wex.runLegacyWalletDbTx(async (tx) => { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { return; } planchet.lastError = errDetail; - await tx.planchets.put(planchet); + await tx.wtx.upsertPlanchet(planchet); }); } @@ -1853,10 +1853,10 @@ async function processPlanchetVerifyAndStoreCoin( logger.trace(`checking and storing planchet idx=${coinIdx}`); const d = await wex.runLegacyWalletDbTx(async (tx) => { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { return; } @@ -1915,10 +1915,10 @@ async function processPlanchetVerifyAndStoreCoin( if (!rsaVerifyResp.valid) { await wex.runLegacyWalletDbTx(async (tx) => { - const planchet = await tx.planchets.indexes.byGroupAndIndex.get([ + const planchet = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroup.withdrawalGroupId, coinIdx, - ]); + ); if (!planchet) { return; } @@ -1927,7 +1927,7 @@ async function processPlanchetVerifyAndStoreCoin( {}, "invalid signature from the exchange after unblinding", ); - await tx.planchets.put(planchet); + await tx.wtx.upsertPlanchet(planchet); }); return; } @@ -1967,13 +1967,13 @@ async function processPlanchetVerifyAndStoreCoin( wgContext.planchetsFinished.add(planchet.coinPub); await wex.runLegacyWalletDbTx(async (tx) => { - const p = await tx.planchets.get(planchetCoinPub); + const p = await tx.wtx.getPlanchet(planchetCoinPub); if (!p || p.planchetStatus === PlanchetStatus.WithdrawalDone) { return; } p.planchetStatus = PlanchetStatus.WithdrawalDone; p.lastError = undefined; - await tx.planchets.put(p); + await tx.wtx.upsertPlanchet(p); await makeCoinAvailable(wex, tx.wtx, coin); }); } @@ -2217,12 +2217,7 @@ async function processQueryReserve( await storeKnownBankAccount(tx, currency, lastOrigin); } if (redoSelection) { - const planchetKeys = await tx.planchets.indexes.byGroup.getAllKeys( - wg.withdrawalGroupId, - ); - for (const pk of planchetKeys) { - await tx.planchets.delete(pk); - } + await tx.wtx.deletePlanchetsByGroup(wg.withdrawalGroupId); const candidates = await getWithdrawableDenomsTx( wex, tx, @@ -2256,12 +2251,12 @@ interface WithdrawalGroupStatusInfo { /** * Cached withdrawal group record from the database. */ - wgRecord: WithdrawalGroupRecord; + wgRecord: WalletWithdrawalGroup; } async function processWithdrawalGroupAbortingBank( wex: WalletExecutionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { const { withdrawalGroupId } = withdrawalGroup; const ctx = new WithdrawTransactionContext(wex, withdrawalGroupId); @@ -2292,7 +2287,7 @@ async function processWithdrawalGroupAbortingBank( async function processWithdrawalGroupPendingKyc( wex: WalletExecutionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { const ctx = new WithdrawTransactionContext( wex, @@ -2378,7 +2373,7 @@ async function redenominateWithdrawal( logger.trace(`redenominating withdrawal group ${withdrawalGroupId}`); await wex.runLegacyWalletDbTx(async (tx) => { - const wg = await tx.withdrawalGroups.get(withdrawalGroupId); + const wg = await tx.wtx.getWithdrawalGroup(withdrawalGroupId); if (!wg) { return; } @@ -2468,10 +2463,10 @@ async function redenominateWithdrawal( for (let j = 0; j < sel.count; j++) { const ci = coinIndex + j; - const p = await tx.planchets.indexes.byGroupAndIndex.get([ + const p = await tx.wtx.getPlanchetByGroupAndIndex( withdrawalGroupId, ci, - ]); + ); if (!p) { // Maybe planchet wasn't yet generated. // No problem! @@ -2485,7 +2480,7 @@ async function redenominateWithdrawal( // re-denomination later. logger.info(`aborting planchet #${coinIndex}`); p.planchetStatus = PlanchetStatus.AbortedReplaced; - await tx.planchets.put(p); + await tx.wtx.upsertPlanchet(p); } } @@ -2516,13 +2511,13 @@ async function redenominateWithdrawal( if (logger.shouldLogTrace()) { logger.trace(`merged denom sel: ${j2s(mergedSel)}`); } - await tx.withdrawalGroups.put(wg); + await tx.wtx.upsertWithdrawalGroup(wg); }); } async function processWithdrawalGroupPendingReady( wex: WalletExecutionContext, - withdrawalGroup: WithdrawalGroupRecord, + withdrawalGroup: WalletWithdrawalGroup, ): Promise<TaskRunResult> { const { withdrawalGroupId } = withdrawalGroup; const ctx = new WithdrawTransactionContext(wex, withdrawalGroupId); @@ -2605,7 +2600,7 @@ async function processWithdrawalGroupPendingReady( await wex.runLegacyWalletDbTx(async (tx) => { const planchets = - await tx.planchets.indexes.byGroup.getAll(withdrawalGroupId); + await tx.wtx.getPlanchetsByGroup(withdrawalGroupId); for (const p of planchets) { if (p.planchetStatus === PlanchetStatus.WithdrawalDone) { wgContext.planchetsFinished.add(p.coinPub); @@ -2681,7 +2676,7 @@ async function processWithdrawalGroupPendingReady( await wex.runLegacyWalletDbTx(async (tx) => { const planchets = - await tx.planchets.indexes.byGroup.getAll(withdrawalGroupId); + await tx.wtx.getPlanchetsByGroup(withdrawalGroupId); for (const p of planchets) { if (p.planchetStatus !== PlanchetStatus.Pending) { continue; @@ -2721,7 +2716,7 @@ async function processWithdrawalGroupPendingReady( } const groupPlanchets = - await tx.planchets.indexes.byGroup.getAll(withdrawalGroupId); + await tx.wtx.getPlanchetsByGroup(withdrawalGroupId); for (const x of groupPlanchets) { switch (x.planchetStatus) { case PlanchetStatus.KycRequired: @@ -2805,7 +2800,7 @@ export async function processWithdrawalGroup( logger.trace("processing withdrawal group", withdrawalGroupId); const withdrawalGroup = await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.get(withdrawalGroupId), + tx.wtx.getWithdrawalGroup(withdrawalGroupId), ); if (!withdrawalGroup) { @@ -3080,13 +3075,13 @@ async function getWithdrawalGroupRecordTx( req: { withdrawalGroupId: string; }, -): Promise<WithdrawalGroupRecord | undefined> { +): Promise<WalletWithdrawalGroup | undefined> { return await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.get(req.withdrawalGroupId), + tx.wtx.getWithdrawalGroup(req.withdrawalGroupId), ); } -export function getReserveRequestTimeout(r: WithdrawalGroupRecord): Duration { +export function getReserveRequestTimeout(r: WalletWithdrawalGroup): Duration { return { d_ms: 60000 }; } @@ -3124,7 +3119,7 @@ async function registerReserveWithBank( isFlexibleAmount: boolean, ): Promise<TaskRunResult> { const withdrawalGroup = await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.get(withdrawalGroupId), + tx.wtx.getWithdrawalGroup(withdrawalGroupId), ); const ctx = new WithdrawTransactionContext(wex, withdrawalGroupId); switch (withdrawalGroup?.status) { @@ -3464,7 +3459,7 @@ async function processReserveBankStatus( } export interface PrepareCreateWithdrawalGroupResult { - withdrawalGroup: WithdrawalGroupRecord; + withdrawalGroup: WalletWithdrawalGroup; transactionId: string; creationInfo?: { amount: AmountJson; @@ -3520,7 +3515,7 @@ export async function internalPrepareCreateWithdrawalGroup( withdrawalGroupId = args.forcedWithdrawalGroupId; const wgId = withdrawalGroupId; const existingWg = await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.get(wgId), + tx.wtx.getWithdrawalGroup(wgId), ); if (existingWg) { @@ -3549,7 +3544,7 @@ export async function internalPrepareCreateWithdrawalGroup( ); } - const withdrawalGroup: WithdrawalGroupRecord = { + const withdrawalGroup: WalletWithdrawalGroup = { // next fields will be undefined if exchange or amount is not specified denomsSel: initialDenomSel, exchangeBaseUrl: exchangeBaseUrl, @@ -3589,7 +3584,7 @@ export async function internalPrepareCreateWithdrawalGroup( } export interface PerformCreateWithdrawalGroupResult { - withdrawalGroup: WithdrawalGroupRecord; + withdrawalGroup: WalletWithdrawalGroup; } export async function internalPerformCreateWithdrawalGroup( @@ -3608,7 +3603,7 @@ export async function internalPerformCreateWithdrawalGroup( withdrawalGroup: existingWg, }; } - await tx.withdrawalGroups.add(withdrawalGroup); + await tx.wtx.upsertWithdrawalGroup(withdrawalGroup); await tx.wtx.upsertReserve({ reservePub: withdrawalGroup.reservePub, reservePriv: withdrawalGroup.reservePriv, @@ -3666,7 +3661,7 @@ export async function internalCreateWithdrawalGroup( wgInfo: WgInfo; isForeignAccount?: boolean; }, -): Promise<WithdrawalGroupRecord> { +): Promise<WalletWithdrawalGroup> { const prep = await internalPrepareCreateWithdrawalGroup(wex, args); const ctx = new WithdrawTransactionContext( wex, @@ -3688,7 +3683,7 @@ export async function prepareBankIntegratedWithdrawal( }, ): Promise<PrepareBankIntegratedWithdrawalResponse> { const existingWithdrawalGroup = await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.indexes.byTalerWithdrawUri.get(req.talerWithdrawUri), + tx.wtx.getWithdrawalGroupByTalerWithdrawUri(req.talerWithdrawUri), ); const parsedUri = Result.orUndefined( @@ -3821,7 +3816,7 @@ export async function confirmWithdrawal( throw Error("invalid withdrawal transaction ID"); } const withdrawalGroup = await wex.runLegacyWalletDbTx((tx) => - tx.withdrawalGroups.get(parsedTx.withdrawalGroupId), + tx.wtx.getWithdrawalGroup(parsedTx.withdrawalGroupId), ); if (!withdrawalGroup) { @@ -4147,7 +4142,7 @@ export async function acceptBankIntegratedWithdrawal( const newWithdrawralGroup = await wex.runLegacyWalletDbTx( async (tx) => - await tx.withdrawalGroups.indexes.byTalerWithdrawUri.get( + await tx.wtx.getWithdrawalGroupByTalerWithdrawUri( req.talerWithdrawUri, ), ); @@ -4399,7 +4394,7 @@ export async function waitWithdrawalFinal( async checkState() { // Check if withdrawal is final const wg = await ctx.wex.runLegacyWalletDbTx( - async (tx) => await tx.withdrawalGroups.get(ctx.withdrawalGroupId), + async (tx) => await tx.wtx.getWithdrawalGroup(ctx.withdrawalGroupId), ); if (!wg) { // Must've been deleted, we consider that final.