commit e5673419eb668491568075f06590a357a174bb0a
parent 3b91c7c8c1d0db457ad28cd832cbcc61e7b1cd2a
Author: Florian Dold <dold@taler.net>
Date: Sat, 18 Jul 2026 20:40:04 +0200
db: add refresh group and session accessors
Diffstat:
11 files changed, 280 insertions(+), 192 deletions(-)
diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts
@@ -89,10 +89,10 @@ import {
PurchaseStatus,
RefreshOperationStatus,
WithdrawalGroupStatus,
+ WalletRefreshGroup,
} from "./db-common.js";
import {
DonationSummaryRecord,
- RefreshGroupRecord,
WithdrawalRecordType,
} from "./db-indexeddb.js";
import { WalletDbTransaction } from "./dbtx.js";
@@ -121,7 +121,7 @@ interface WalletBalance {
}
function computeRefreshGroupAvailableAmountForExchanges(
- r: RefreshGroupRecord,
+ r: WalletRefreshGroup,
restrictExchanges: AllowedExchangeInfo[] | undefined,
): AmountJson {
// Don't count finished refreshes, since the refresh already resulted
diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts
@@ -70,6 +70,7 @@ import {
WalletCoin,
WalletDepositGroup,
WalletRecoupGroup,
+ WalletRefreshGroup,
} from "./db-common.js";
import {
ExchangeEntryRecord,
@@ -78,7 +79,6 @@ import {
PeerPushCreditRecord,
PeerPushDebitRecord,
PurchaseRecord,
- RefreshGroupRecord,
WithdrawalGroupRecord,
} from "./db-indexeddb.js";
import { WalletDbTransaction } from "./dbtx.js";
@@ -822,7 +822,7 @@ export namespace TaskIdentifiers {
)}` as TaskIdStr;
}
export function forRefresh(
- refreshGroupRecord: RefreshGroupRecord,
+ refreshGroupRecord: WalletRefreshGroup,
): TaskIdStr {
return `${PendingTaskType.Refresh}:${refreshGroupRecord.refreshGroupId}` as TaskIdStr;
}
diff --git a/packages/taler-wallet-core/src/db-common.ts b/packages/taler-wallet-core/src/db-common.ts
@@ -31,6 +31,8 @@ import {
DenominationInfo,
TransferOptionRaw,
CoinRefreshRequest,
+ ExchangeRefundRequest,
+ RefreshReason,
CoinStatus,
AgeCommitmentProof,
TransactionIdStr,
@@ -389,6 +391,118 @@ export interface WalletReserve {
amlReview?: boolean;
}
+export interface WalletRefreshGroupPerExchangeInfo {
+ /**
+ * (Expected) output once the refresh group succeeded.
+ */
+ outputEffective: AmountString;
+}
+
+/**
+ * Group of refresh operations. The refreshed coins do not
+ * have to belong to the same exchange, but must have the same
+ * currency.
+ */
+export interface WalletRefreshGroup {
+ operationStatus: RefreshOperationStatus;
+
+ /**
+ * Unique, randomly generated identifier for this group of
+ * refresh operations.
+ */
+ refreshGroupId: string;
+
+ /**
+ * Currency of this refresh group.
+ */
+ currency: string;
+
+ /**
+ * Reason why this refresh group has been created.
+ */
+ reason: RefreshReason;
+
+ originatingTransactionId?: string;
+
+ oldCoinPubs: string[];
+
+ inputPerCoin: AmountString[];
+
+ expectedOutputPerCoin: AmountString[];
+
+ infoPerExchange?: Record<string, WalletRefreshGroupPerExchangeInfo>;
+
+ /**
+ * Flag for each coin whether refreshing finished.
+ * If a coin can't be refreshed (remaining value too small),
+ * it will be marked as finished, but no refresh session will
+ * be created.
+ */
+ statusPerCoin: RefreshCoinStatus[];
+
+ /**
+ * Refund requests that might still be necessary
+ * before the refresh can work.
+ */
+ refundRequests: { [n: number]: ExchangeRefundRequest };
+
+ timestampCreated: DbPreciseTimestamp;
+
+ failReason?: TalerErrorDetail;
+
+ /**
+ * Timestamp when the refresh session finished.
+ */
+ timestampFinished: DbPreciseTimestamp | undefined;
+}
+
+/**
+ * Ongoing refresh
+ */
+export interface WalletRefreshSession {
+ refreshGroupId: string;
+
+ /**
+ * Index of the coin in the refresh group.
+ */
+ coinIndex: number;
+
+ /**
+ * If this field is set, it's a V2 refresh session.
+ */
+ sessionPublicSeed?: string;
+
+ /**
+ * Sum of the value of denominations we want
+ * to withdraw in this session, without fees.
+ */
+ amountRefreshOutput: AmountString;
+
+ /**
+ * Hashed denominations of the newly requested coins.
+ */
+ newDenoms: {
+ denomPubHash: string;
+ count: number;
+ }[];
+
+ /**
+ * The no-reveal-index after we've done the melting.
+ */
+ norevealIndex?: number;
+
+ /**
+ * Last error response from the exchange.
+ *
+ * FIXME: We don't store the last HTTP status yet.
+ */
+ lastError?: TalerErrorDetail;
+
+ // Reserved legacy fields:
+ // * sessionSecretSeed: string
+ // (legacy v1 refresh)
+}
+
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
@@ -122,6 +122,9 @@ import {
WalletDepositTrackingInfo,
WalletDepositInfoPerExchange,
WalletRecoupGroup,
+ WalletRefreshGroup,
+ WalletRefreshSession,
+ WalletRefreshGroupPerExchangeInfo,
WalletReserve,
WalletCoin,
WalletCoinAvailability,
@@ -703,118 +706,6 @@ export namespace TokenRecord {
}
}
-export interface RefreshGroupPerExchangeInfo {
- /**
- * (Expected) output once the refresh group succeeded.
- */
- outputEffective: AmountString;
-}
-
-/**
- * Group of refresh operations. The refreshed coins do not
- * have to belong to the same exchange, but must have the same
- * currency.
- */
-export interface RefreshGroupRecord {
- operationStatus: RefreshOperationStatus;
-
- /**
- * Unique, randomly generated identifier for this group of
- * refresh operations.
- */
- refreshGroupId: string;
-
- /**
- * Currency of this refresh group.
- */
- currency: string;
-
- /**
- * Reason why this refresh group has been created.
- */
- reason: RefreshReason;
-
- originatingTransactionId?: string;
-
- oldCoinPubs: string[];
-
- inputPerCoin: AmountString[];
-
- expectedOutputPerCoin: AmountString[];
-
- infoPerExchange?: Record<string, RefreshGroupPerExchangeInfo>;
-
- /**
- * Flag for each coin whether refreshing finished.
- * If a coin can't be refreshed (remaining value too small),
- * it will be marked as finished, but no refresh session will
- * be created.
- */
- statusPerCoin: RefreshCoinStatus[];
-
- /**
- * Refund requests that might still be necessary
- * before the refresh can work.
- */
- refundRequests: { [n: number]: ExchangeRefundRequest };
-
- timestampCreated: DbPreciseTimestamp;
-
- failReason?: TalerErrorDetail;
-
- /**
- * Timestamp when the refresh session finished.
- */
- timestampFinished: DbPreciseTimestamp | undefined;
-}
-
-/**
- * Ongoing refresh
- */
-export interface RefreshSessionRecord {
- refreshGroupId: string;
-
- /**
- * Index of the coin in the refresh group.
- */
- coinIndex: number;
-
- /**
- * If this field is set, it's a V2 refresh session.
- */
- sessionPublicSeed?: string;
-
- /**
- * Sum of the value of denominations we want
- * to withdraw in this session, without fees.
- */
- amountRefreshOutput: AmountString;
-
- /**
- * Hashed denominations of the newly requested coins.
- */
- newDenoms: {
- denomPubHash: string;
- count: number;
- }[];
-
- /**
- * The no-reveal-index after we've done the melting.
- */
- norevealIndex?: number;
-
- /**
- * Last error response from the exchange.
- *
- * FIXME: We don't store the last HTTP status yet.
- */
- lastError?: TalerErrorDetail;
-
- // Reserved legacy fields:
- // * sessionSecretSeed: string
- // (legacy v1 refresh)
-}
-
/**
* Partial information about the downloaded proposal.
* Only contains data that is relevant for indexing on the
@@ -2023,7 +1914,7 @@ export const WalletIndexedDbStoresV1 = {
}),
refreshGroups: describeStore(
"refreshGroups",
- describeContents<RefreshGroupRecord>({
+ describeContents<WalletRefreshGroup>({
keyPath: "refreshGroupId",
}),
{
@@ -2039,7 +1930,7 @@ export const WalletIndexedDbStoresV1 = {
),
refreshSessions: describeStore(
"refreshSessions",
- describeContents<RefreshSessionRecord>({
+ describeContents<WalletRefreshSession>({
keyPath: ["refreshGroupId", "coinIndex"],
}),
{
diff --git a/packages/taler-wallet-core/src/dbtx-indexeddb.ts b/packages/taler-wallet-core/src/dbtx-indexeddb.ts
@@ -57,10 +57,11 @@ import {
WalletDepositGroup,
WalletRecoupGroup,
WalletReserve,
+ WalletRefreshGroup,
+ WalletRefreshSession,
} from "./db-common.js";
import type {
ExchangeEntryRecord,
- RefreshGroupRecord,
WithdrawalGroupRecord,
ExchangeDetailsRecord,
DonationSummaryRecord,
@@ -268,6 +269,62 @@ export class IdbWalletTransaction implements WalletDbTransaction {
});
}
+ async getRefreshGroup(
+ refreshGroupId: string,
+ ): Promise<WalletRefreshGroup | undefined> {
+ const tx = this.tx;
+ return await tx.refreshGroups.get(refreshGroupId);
+ }
+
+ async upsertRefreshGroup(rec: WalletRefreshGroup): Promise<void> {
+ const tx = this.tx;
+ await tx.refreshGroups.put(rec);
+ }
+
+ async deleteRefreshGroup(refreshGroupId: string): Promise<void> {
+ const tx = this.tx;
+ await tx.refreshGroups.delete(refreshGroupId);
+ }
+
+ async getRefreshGroupsByOriginatingTransaction(
+ transactionId: string,
+ ): Promise<WalletRefreshGroup[]> {
+ const tx = this.tx;
+ return await tx.refreshGroups.indexes.byOriginatingTransactionId.getAll(
+ transactionId,
+ );
+ }
+
+ async getRefreshSession(
+ refreshGroupId: string,
+ coinIndex: number,
+ ): Promise<WalletRefreshSession | undefined> {
+ const tx = this.tx;
+ return await tx.refreshSessions.get([refreshGroupId, coinIndex]);
+ }
+
+ async upsertRefreshSession(rec: WalletRefreshSession): Promise<void> {
+ const tx = this.tx;
+ await tx.refreshSessions.put(rec);
+ }
+
+ async deleteRefreshSession(
+ refreshGroupId: string,
+ coinIndex: number,
+ ): Promise<void> {
+ const tx = this.tx;
+ await tx.refreshSessions.delete([refreshGroupId, coinIndex]);
+ }
+
+ async getRefreshSessionsByGroup(
+ refreshGroupId: string,
+ ): Promise<WalletRefreshSession[]> {
+ const tx = this.tx;
+ return await tx.refreshSessions.indexes.byRefreshGroupId.getAll(
+ refreshGroupId,
+ );
+ }
+
async getRecoupGroup(
recoupGroupId: string,
): Promise<WalletRecoupGroup | undefined> {
@@ -761,7 +818,7 @@ export class IdbWalletTransaction implements WalletDbTransaction {
return await this.tx.coinAvailability.iter().toArray();
}
- async getActiveRefreshGroups(): Promise<RefreshGroupRecord[]> {
+ async getActiveRefreshGroups(): Promise<WalletRefreshGroup[]> {
return await this.tx.refreshGroups.indexes.byStatus.getAll(
getActiveKeyRange(),
);
diff --git a/packages/taler-wallet-core/src/dbtx.ts b/packages/taler-wallet-core/src/dbtx.ts
@@ -61,10 +61,11 @@ import {
WalletDepositGroup,
WalletRecoupGroup,
WalletReserve,
+ WalletRefreshGroup,
+ WalletRefreshSession,
} from "./db-common.js";
import type {
ExchangeEntryRecord,
- RefreshGroupRecord,
WithdrawalGroupRecord,
ExchangeDetailsRecord,
DonationSummaryRecord,
@@ -176,6 +177,31 @@ export interface WalletDbTransaction {
*/
upsertContractTerms(rec: WalletContractTerms): Promise<void>;
+ getRefreshGroup(
+ refreshGroupId: string,
+ ): Promise<WalletRefreshGroup | undefined>;
+
+ upsertRefreshGroup(rec: WalletRefreshGroup): Promise<void>;
+
+ deleteRefreshGroup(refreshGroupId: string): Promise<void>;
+
+ getRefreshGroupsByOriginatingTransaction(
+ transactionId: string,
+ ): Promise<WalletRefreshGroup[]>;
+
+ getRefreshSession(
+ refreshGroupId: string,
+ coinIndex: number,
+ ): Promise<WalletRefreshSession | undefined>;
+
+ upsertRefreshSession(rec: WalletRefreshSession): Promise<void>;
+
+ deleteRefreshSession(refreshGroupId: string, coinIndex: number): Promise<void>;
+
+ getRefreshSessionsByGroup(
+ refreshGroupId: string,
+ ): Promise<WalletRefreshSession[]>;
+
getRecoupGroup(
recoupGroupId: string,
): Promise<WalletRecoupGroup | undefined>;
@@ -365,7 +391,7 @@ export interface WalletDbTransaction {
getCoinAvailabilities(): Promise<WalletCoinAvailability[]>;
- getActiveRefreshGroups(): Promise<RefreshGroupRecord[]>;
+ getActiveRefreshGroups(): Promise<WalletRefreshGroup[]>;
getActiveWithdrawalGroups(): Promise<WithdrawalGroupRecord[]>;
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
@@ -988,7 +988,7 @@ async function waitForRefreshOnDepositGroup(
await genericWaitForState(wex, {
async checkState() {
return await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId);
+ const refreshGroup = await tx.wtx.getRefreshGroup(abortRefreshGroupId);
switch (refreshGroup?.operationStatus) {
case undefined:
case RefreshOperationStatus.Failed:
@@ -1007,7 +1007,7 @@ async function waitForRefreshOnDepositGroup(
});
const didTransition = await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId);
+ const refreshGroup = await tx.wtx.getRefreshGroup(abortRefreshGroupId);
let newOpState: DepositOperationStatus | undefined;
switch (refreshGroup?.operationStatus) {
case undefined: {
diff --git a/packages/taler-wallet-core/src/dev-experiments.ts b/packages/taler-wallet-core/src/dev-experiments.ts
@@ -63,10 +63,10 @@ import {
WithdrawalGroupStatus,
timestampPreciseToDb,
timestampProtocolToDb,
+ WalletRefreshGroup,
} from "./db-common.js";
import {
DenomLossEventRecord,
- RefreshGroupRecord,
WithdrawalRecordType,
} from "./db-indexeddb.js";
import {
@@ -185,7 +185,7 @@ export async function applyDevExperiment(
case "insert-pending-refresh": {
const refreshGroupId = encodeCrock(getRandomBytes(32));
await wex.runLegacyWalletDbTx(async (tx) => {
- const newRg: RefreshGroupRecord = {
+ const newRg: WalletRefreshGroup = {
currency: "TESTKUDOS",
expectedOutputPerCoin: [],
inputPerCoin: [],
@@ -200,7 +200,7 @@ export async function applyDevExperiment(
infoPerExchange: {},
refundRequests: {},
};
- await tx.refreshGroups.put(newRg);
+ await tx.wtx.upsertRefreshGroup(newRg);
const ctx = new RefreshTransactionContext(wex, refreshGroupId);
await ctx.updateTransactionMeta(tx);
});
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -4351,7 +4351,7 @@ export async function migrateExchange(
rec.infoPerExchange[req.newExchangeBaseUrl] =
rec.infoPerExchange[req.oldExchangeBaseUrl];
delete rec.infoPerExchange[req.oldExchangeBaseUrl];
- await tx.refreshGroups.put(rec);
+ await tx.wtx.upsertRefreshGroup(rec);
}
});
}
diff --git a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts
@@ -645,7 +645,7 @@ async function processPeerPullDebitAbortingRefresh(
checkLogicInvariant(!!abortRefreshGroupId);
const ctx = new PeerPullDebitTransactionContext(wex, peerPullDebitId);
await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId);
+ const refreshGroup = await tx.wtx.getRefreshGroup(abortRefreshGroupId);
const [rec, h] = await ctx.getRecordHandle(tx);
if (!rec) {
return;
diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts
@@ -99,12 +99,12 @@ import {
WalletCoinAvailability,
WalletCoinHistory,
WalletCoin,
+ WalletRefreshGroupPerExchangeInfo,
+ WalletRefreshGroup,
+ WalletRefreshSession,
} from "./db-common.js";
import {
CoinSourceType,
- RefreshGroupPerExchangeInfo,
- RefreshGroupRecord,
- RefreshSessionRecord,
} from "./db-indexeddb.js";
import { selectWithdrawalDenominations } from "./denomSelection.js";
import {
@@ -151,7 +151,7 @@ export class RefreshTransactionContext implements TransactionContext {
}
async updateTransactionMeta(tx: LegacyWalletTxHandle): Promise<void> {
- const rgRec = await tx.refreshGroups.get(this.refreshGroupId);
+ const rgRec = await tx.wtx.getRefreshGroup(this.refreshGroupId);
if (!rgRec) {
await tx.wtx.deleteTransactionMeta(this.transactionId);
return;
@@ -174,7 +174,7 @@ export class RefreshTransactionContext implements TransactionContext {
async lookupFullTransaction(
tx: LegacyWalletTxHandle,
): Promise<Transaction | undefined> {
- const refreshGroupRecord = await tx.refreshGroups.get(this.refreshGroupId);
+ const refreshGroupRecord = await tx.wtx.getRefreshGroup(this.refreshGroupId);
if (!refreshGroupRecord) {
return undefined;
}
@@ -222,16 +222,16 @@ export class RefreshTransactionContext implements TransactionContext {
async getRecordHandle(
tx: LegacyWalletTxHandle,
): Promise<
- [RefreshGroupRecord | undefined, RecordHandle<RefreshGroupRecord>]
+ [WalletRefreshGroup | undefined, RecordHandle<WalletRefreshGroup>]
> {
- return getGenericRecordHandle<RefreshGroupRecord>(
+ return getGenericRecordHandle<WalletRefreshGroup>(
this,
tx.wtx,
- async () => tx.refreshGroups.get(this.refreshGroupId),
+ async () => tx.wtx.getRefreshGroup(this.refreshGroupId),
async (r) => {
- await tx.refreshGroups.put(r);
+ await tx.wtx.upsertRefreshGroup(r);
},
- async () => tx.refreshGroups.delete(this.refreshGroupId),
+ async () => tx.wtx.deleteRefreshGroup(this.refreshGroupId),
(r) => computeRefreshTransactionState(r),
(r) => r.operationStatus,
() => this.updateTransactionMeta(tx),
@@ -252,14 +252,14 @@ export class RefreshTransactionContext implements TransactionContext {
);
return;
}
- const sessions = await tx.refreshSessions.indexes.byRefreshGroupId.getAll(
+ const sessions = await tx.wtx.getRefreshSessionsByGroup(
rg.refreshGroupId,
);
for (const s of sessions) {
- await tx.refreshSessions.delete([s.refreshGroupId, s.coinIndex]);
+ await tx.wtx.deleteRefreshSession(s.refreshGroupId, s.coinIndex);
}
await h.update(undefined);
- await tx.refreshGroups.delete(rg.refreshGroupId);
+ await tx.wtx.deleteRefreshGroup(rg.refreshGroupId);
}
async userSuspendTransaction(): Promise<void> {
@@ -448,7 +448,7 @@ async function getCoinAvailabilityForDenom(
async function initRefreshSession(
wex: WalletExecutionContext,
tx: LegacyWalletTxHandle,
- refreshGroup: RefreshGroupRecord,
+ refreshGroup: WalletRefreshGroup,
coinIndex: number,
): Promise<void> {
const refreshGroupId = refreshGroup.refreshGroupId;
@@ -525,7 +525,7 @@ async function initRefreshSession(
await tx.coinAvailability.put(car);
}
- const newSession: RefreshSessionRecord = {
+ const newSession: WalletRefreshSession = {
coinIndex,
refreshGroupId,
norevealIndex: undefined,
@@ -535,7 +535,7 @@ async function initRefreshSession(
})),
amountRefreshOutput: Amounts.stringify(newCoinDenoms.totalCoinValue),
};
- await tx.refreshSessions.put(newSession);
+ await tx.wtx.upsertRefreshSession(newSession);
}
/**
@@ -546,8 +546,8 @@ async function initRefreshSession(
async function destroyRefreshSession(
wex: WalletExecutionContext,
tx: LegacyWalletTxHandle,
- refreshGroup: RefreshGroupRecord,
- refreshSession: RefreshSessionRecord,
+ refreshGroup: WalletRefreshGroup,
+ refreshSession: WalletRefreshSession,
): Promise<void> {
for (let i = 0; i < refreshSession.newDenoms.length; i++) {
const oldCoin = await tx.coins.get(
@@ -578,7 +578,7 @@ async function destroyRefreshSession(
}
}
-function getRefreshRequestTimeout(rg: RefreshGroupRecord): Duration {
+function getRefreshRequestTimeout(rg: WalletRefreshGroup): Duration {
return Duration.fromSpec({
seconds: 60,
});
@@ -599,14 +599,14 @@ async function refreshMelt(
): Promise<void> {
const ctx = new RefreshTransactionContext(wex, refreshGroupId);
const d = await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshGroup = await tx.refreshGroups.get(refreshGroupId);
+ const refreshGroup = await tx.wtx.getRefreshGroup(refreshGroupId);
if (!refreshGroup) {
return;
}
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
return;
}
@@ -664,10 +664,10 @@ async function refreshMelt(
}
const seed = encodeCrock(getRandomBytes(64));
const updatedSession = await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
return undefined;
}
@@ -675,7 +675,7 @@ async function refreshMelt(
return refreshSession;
}
refreshSession.sessionPublicSeed = seed;
- await tx.refreshSessions.put(refreshSession);
+ await tx.wtx.upsertRefreshSession(refreshSession);
return refreshSession;
});
if (!updatedSession) {
@@ -784,14 +784,14 @@ async function refreshMelt(
refreshSession.norevealIndex = norevealIndex;
await wex.runLegacyWalletDbTx(async (tx) => {
- const rg = await tx.refreshGroups.get(refreshGroupId);
+ const rg = await tx.wtx.getRefreshGroup(refreshGroupId);
if (!rg) {
return;
}
if (rg.timestampFinished) {
return;
}
- const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]);
+ const rs = await tx.wtx.getRefreshSession(refreshGroupId, coinIndex);
if (!rs) {
return;
}
@@ -799,7 +799,7 @@ async function refreshMelt(
return;
}
rs.norevealIndex = norevealIndex;
- await tx.refreshSessions.put(rs);
+ await tx.wtx.upsertRefreshSession(rs);
});
}
@@ -834,22 +834,22 @@ async function handleRefreshMeltGone(
return;
}
rg.statusPerCoin[coinIndex] = RefreshCoinStatus.PendingRedenominate;
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
ctx.refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
throw Error("db invariant failed: missing refresh session in database");
}
refreshSession.lastError = errDetails;
- await tx.refreshSessions.put(refreshSession);
+ await tx.wtx.upsertRefreshSession(refreshSession);
await h.update(rg);
});
}
async function handleRefreshMeltConflict(
ctx: RefreshTransactionContext,
- refreshGroup: RefreshGroupRecord,
+ refreshGroup: WalletRefreshGroup,
coinIndex: number,
errDetails: TalerErrorDetail,
meltValueWithFee: AmountLike,
@@ -877,12 +877,12 @@ async function handleRefreshMeltConflict(
switch (httpResp.status) {
case HttpStatusCode.Ok:
await ctx.wex.runLegacyWalletDbTx(async (tx) => {
- const rg = await tx.refreshGroups.get(refreshGroup.refreshGroupId);
+ const rg = await tx.wtx.getRefreshGroup(refreshGroup.refreshGroupId);
if (!rg || rg.operationStatus != RefreshOperationStatus.Pending) {
return;
}
delete rg.refundRequests[coinIndex];
- await tx.refreshGroups.put(rg);
+ await tx.wtx.upsertRefreshGroup(rg);
});
break;
default:
@@ -935,28 +935,28 @@ async function handleRefreshMeltConflict(
}
if (Amounts.isZero(historyJson.balance)) {
rg.statusPerCoin[coinIndex] = RefreshCoinStatus.Failed;
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
ctx.refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
throw Error("db invariant failed: missing refresh session in database");
}
refreshSession.lastError = errDetails;
- await tx.refreshSessions.put(refreshSession);
+ await tx.wtx.upsertRefreshSession(refreshSession);
await h.update(rg);
} else {
// Try again with new denoms!
rg.inputPerCoin[coinIndex] = historyJson.balance;
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
ctx.refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
throw Error("db invariant failed: missing refresh session in database");
}
await destroyRefreshSession(ctx.wex, tx, rg, refreshSession);
- await tx.refreshSessions.delete([ctx.refreshGroupId, coinIndex]);
+ await tx.wtx.deleteRefreshSession(ctx.refreshGroupId, coinIndex);
await initRefreshSession(ctx.wex, tx, rg, coinIndex);
}
});
@@ -989,15 +989,15 @@ async function handleRefreshMeltNotFound(
return;
}
rg.statusPerCoin[coinIndex] = RefreshCoinStatus.Failed;
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
ctx.refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
throw Error("db invariant failed: missing refresh session in database");
}
refreshSession.lastError = errDetails;
- await tx.refreshSessions.put(refreshSession);
+ await tx.wtx.upsertRefreshSession(refreshSession);
await destroyRefreshSession(ctx.wex, tx, rg, refreshSession);
await h.update(rg);
});
@@ -1013,14 +1013,14 @@ async function refreshReveal(
);
const ctx = new RefreshTransactionContext(wex, refreshGroupId);
const d = await wex.runLegacyWalletDbTx(async (tx) => {
- const refreshGroup = await tx.refreshGroups.get(refreshGroupId);
+ const refreshGroup = await tx.wtx.getRefreshGroup(refreshGroupId);
if (!refreshGroup) {
return;
}
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
return;
}
@@ -1186,7 +1186,7 @@ async function refreshReveal(
if (rg.statusPerCoin[coinIndex] !== RefreshCoinStatus.Pending) {
return;
}
- const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]);
+ const rs = await tx.wtx.getRefreshSession(refreshGroupId, coinIndex);
if (!rs) {
return;
}
@@ -1241,16 +1241,16 @@ async function handleRefreshRevealError(
return;
}
rg.statusPerCoin[coinIndex] = RefreshCoinStatus.Failed;
- const refreshSession = await tx.refreshSessions.get([
+ const refreshSession = await tx.wtx.getRefreshSession(
ctx.refreshGroupId,
coinIndex,
- ]);
+ );
if (!refreshSession) {
throw Error("db invariant failed: missing refresh session in database");
}
refreshSession.lastError = errDetails;
await destroyRefreshSession(ctx.wex, tx, rg, refreshSession);
- await tx.refreshSessions.put(refreshSession);
+ await tx.wtx.upsertRefreshSession(refreshSession);
await h.update(rg);
});
}
@@ -1266,7 +1266,7 @@ export async function processRefreshGroup(
logger.trace(`processing refresh group ${refreshGroupId}`);
const refreshGroup = await wex.runLegacyWalletDbTx(async (tx) =>
- tx.refreshGroups.get(refreshGroupId),
+ tx.wtx.getRefreshGroup(refreshGroupId),
);
if (!refreshGroup) {
return TaskRunResult.finished();
@@ -1420,17 +1420,17 @@ async function processRefreshSession(
);
let { refreshGroup, refreshSession } = await wex.runLegacyWalletDbTx(
async (tx) => {
- const rg = await tx.refreshGroups.get(refreshGroupId);
- const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]);
+ const rg = await tx.wtx.getRefreshGroup(refreshGroupId);
+ const rs = await tx.wtx.getRefreshSession(refreshGroupId, coinIndex);
if (
rg != null &&
rg.statusPerCoin[coinIndex] === RefreshCoinStatus.PendingRedenominate
) {
- await tx.refreshSessions.delete([refreshGroupId, coinIndex]);
+ await tx.wtx.deleteRefreshSession(refreshGroupId, coinIndex);
await initRefreshSession(wex, tx, rg, coinIndex);
rg.statusPerCoin[coinIndex] = RefreshCoinStatus.Pending;
- await tx.refreshGroups.put(rg);
+ await tx.wtx.upsertRefreshGroup(rg);
}
return {
@@ -1457,7 +1457,7 @@ async function processRefreshSession(
export interface RefreshOutputInfo {
outputPerCoin: AmountJson[];
- perExchangeInfo: Record<string, RefreshGroupPerExchangeInfo>;
+ perExchangeInfo: Record<string, WalletRefreshGroupPerExchangeInfo>;
}
export async function calculateRefreshOutput(
@@ -1468,7 +1468,7 @@ export async function calculateRefreshOutput(
): Promise<RefreshOutputInfo> {
const estimatedOutputPerCoin: AmountJson[] = [];
- const infoPerExchange: Record<string, RefreshGroupPerExchangeInfo> = {};
+ const infoPerExchange: Record<string, WalletRefreshGroupPerExchangeInfo> = {};
for (const ocp of oldCoinPubs) {
const coin = await tx.coins.get(ocp.coinPub);
@@ -1648,7 +1648,7 @@ export async function createRefreshGroup(
}
}
- const refreshGroup: RefreshGroupRecord = {
+ const refreshGroup: WalletRefreshGroup = {
operationStatus: RefreshOperationStatus.Pending,
currency,
timestampFinished: undefined,
@@ -1680,7 +1680,7 @@ export async function createRefreshGroup(
const ctx = new RefreshTransactionContext(wex, refreshGroupId);
- await tx.refreshGroups.put(refreshGroup);
+ await tx.wtx.upsertRefreshGroup(refreshGroup);
await ctx.updateTransactionMeta(tx);
const newTxState = computeRefreshTransactionState(refreshGroup);
@@ -1778,7 +1778,7 @@ async function redenominateRefresh(
}
export function computeRefreshTransactionState(
- rg: RefreshGroupRecord,
+ rg: WalletRefreshGroup,
): TransactionState {
switch (rg.operationStatus) {
case RefreshOperationStatus.Finished:
@@ -1813,7 +1813,7 @@ export function computeRefreshTransactionState(
}
export function computeRefreshTransactionActions(
- rg: RefreshGroupRecord,
+ rg: WalletRefreshGroup,
): TransactionAction[] {
switch (rg.operationStatus) {
case RefreshOperationStatus.Finished:
@@ -1839,7 +1839,7 @@ export function getRefreshesForTransaction(
): Promise<string[]> {
return wex.runLegacyWalletDbTx(async (tx) => {
const groups =
- await tx.refreshGroups.indexes.byOriginatingTransactionId.getAll(
+ await tx.wtx.getRefreshGroupsByOriginatingTransaction(
transactionId,
);
return groups.map((x) =>
@@ -1907,7 +1907,7 @@ export async function waitRefreshFinal(
// Check if refresh is final
const res = await ctx.wex.runLegacyWalletDbTx(async (tx) => {
return {
- rg: await tx.refreshGroups.get(ctx.refreshGroupId),
+ rg: await tx.wtx.getRefreshGroup(ctx.refreshGroupId),
};
});
const { rg } = res;