aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-08-30 15:54:56 +0200
committerFlorian Dold <florian@dold.me>2023-08-30 15:54:56 +0200
commitd19aef746c1e67deaccc7c8cefba008f2f0d46ca (patch)
tree26ee3734f6be8a418dc734761bdb48fc14dbafaf
parent88f7338d7c84ac2a774b483ccff25faf6ceeb879 (diff)
downloadwallet-core-d19aef746c1e67deaccc7c8cefba008f2f0d46ca.tar.xz
wallet-core: towards DD48
-rw-r--r--packages/taler-util/src/time.ts22
-rw-r--r--packages/taler-util/src/wallet-types.ts34
-rw-r--r--packages/taler-wallet-core/src/internal-wallet-state.ts6
-rw-r--r--packages/taler-wallet-core/src/operations/backup/import.ts27
-rw-r--r--packages/taler-wallet-core/src/operations/common.ts80
-rw-r--r--packages/taler-wallet-core/src/operations/exchanges.ts56
-rw-r--r--packages/taler-wallet-core/src/operations/pending.ts28
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts10
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts7
-rw-r--r--packages/taler-wallet-core/src/wallet.ts5
10 files changed, 182 insertions, 93 deletions
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 75b3c7e94..55cda08a5 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -312,6 +312,14 @@ export namespace Duration {
}
export namespace AbsoluteTime {
+ export function getStampMsNow(): number {
+ return new Date().getTime();
+ }
+
+ export function getStampMsNever(): number {
+ return Number.MAX_SAFE_INTEGER;
+ }
+
export function now(): AbsoluteTime {
return {
t_ms: new Date().getTime() + timeshift,
@@ -398,6 +406,13 @@ export namespace AbsoluteTime {
};
}
+ export function fromStampMs(stampMs: number): AbsoluteTime {
+ return {
+ t_ms: stampMs,
+ [opaque_AbsoluteTime]: true,
+ };
+ }
+
export function fromPreciseTimestamp(t: TalerPreciseTimestamp): AbsoluteTime {
if (t.t_s === "never") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
@@ -409,6 +424,13 @@ export namespace AbsoluteTime {
};
}
+ export function toStampMs(at: AbsoluteTime): number {
+ if (at.t_ms === "never") {
+ return Number.MAX_SAFE_INTEGER;
+ }
+ return at.t_ms;
+ }
+
export function toPreciseTimestamp(at: AbsoluteTime): TalerPreciseTimestamp {
if (at.t_ms == "never") {
return {
diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts
index 04fb43ec6..01c1838d5 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -1262,17 +1262,25 @@ export interface ExchangeFullDetails {
}
export enum ExchangeTosStatus {
- New = "new",
+ Pending = "pending",
+ Proposed = "proposed",
Accepted = "accepted",
- Changed = "changed",
- NotFound = "not-found",
- Unknown = "unknown",
}
export enum ExchangeEntryStatus {
- Unknown = "unknown",
- Outdated = "outdated",
- Ok = "ok",
+ Preset = "preset",
+ Ephemeral = "ephemeral",
+ Used = "used",
+}
+
+export enum ExchangeUpdateStatus {
+ Initial = "initial",
+ InitialUpdate = "initial(update)",
+ Suspended = "suspended",
+ Failed = "failed",
+ OutdatedUpdate = "outdated(update)",
+ Ready = "ready",
+ ReadyUpdate = "ready(update)",
}
export interface OperationErrorInfo {
@@ -1285,13 +1293,9 @@ export interface ExchangeListItem {
currency: string | undefined;
paytoUris: string[];
tosStatus: ExchangeTosStatus;
- exchangeStatus: ExchangeEntryStatus;
+ exchangeEntryStatus: ExchangeEntryStatus;
+ exchangeUpdateStatus: ExchangeUpdateStatus;
ageRestrictionOptions: number[];
- /**
- * Permanently added to the wallet, as opposed to just
- * temporarily queried.
- */
- permanent: boolean;
/**
* Information about the last error that occurred when trying
@@ -1370,8 +1374,8 @@ export const codecForExchangeListItem = (): Codec<ExchangeListItem> =>
.property("exchangeBaseUrl", codecForString())
.property("paytoUris", codecForList(codecForString()))
.property("tosStatus", codecForAny())
- .property("exchangeStatus", codecForAny())
- .property("permanent", codecForBoolean())
+ .property("exchangeEntryStatus", codecForAny())
+ .property("exchangeUpdateStatus", codecForAny())
.property("ageRestrictionOptions", codecForList(codecForNumber()))
.build("ExchangeListItem");
diff --git a/packages/taler-wallet-core/src/internal-wallet-state.ts b/packages/taler-wallet-core/src/internal-wallet-state.ts
index 742af89a8..76aee05bd 100644
--- a/packages/taler-wallet-core/src/internal-wallet-state.ts
+++ b/packages/taler-wallet-core/src/internal-wallet-state.ts
@@ -42,7 +42,7 @@ import { HttpRequestLibrary } from "@gnu-taler/taler-util/http";
import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js";
import {
ExchangeDetailsRecord,
- ExchangeRecord,
+ ExchangeEntryRecord,
RefreshReasonDetails,
WalletStoresV1,
} from "./db.js";
@@ -108,7 +108,7 @@ export interface ExchangeOperations {
): Promise<ExchangeDetailsRecord | undefined>;
getExchangeTrust(
ws: InternalWalletState,
- exchangeInfo: ExchangeRecord,
+ exchangeInfo: ExchangeEntryRecord,
): Promise<TrustInfo>;
updateExchangeFromUrl(
ws: InternalWalletState,
@@ -118,7 +118,7 @@ export interface ExchangeOperations {
cancellationToken?: CancellationToken;
},
): Promise<{
- exchange: ExchangeRecord;
+ exchange: ExchangeEntryRecord;
exchangeDetails: ExchangeDetailsRecord;
}>;
}
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts
index a53b624e8..836c65643 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -342,20 +342,19 @@ export async function importBackup(
if (existingExchange) {
continue;
}
- await tx.exchanges.put({
- baseUrl: backupExchange.base_url,
- detailsPointer: {
- currency: backupExchange.currency,
- masterPublicKey: backupExchange.master_public_key,
- updateClock: backupExchange.update_clock,
- },
- permanent: true,
- lastUpdate: undefined,
- nextUpdate: TalerPreciseTimestamp.now(),
- nextRefreshCheck: TalerPreciseTimestamp.now(),
- lastKeysEtag: undefined,
- lastWireEtag: undefined,
- });
+ // await tx.exchanges.put({
+ // baseUrl: backupExchange.base_url,
+ // detailsPointer: {
+ // currency: backupExchange.currency,
+ // masterPublicKey: backupExchange.master_public_key,
+ // updateClock: backupExchange.update_clock,
+ // },
+ // lastUpdate: undefined,
+ // nextUpdate: TalerPreciseTimestamp.now(),
+ // nextRefreshCheck: TalerPreciseTimestamp.now(),
+ // lastKeysEtag: undefined,
+ // lastWireEtag: undefined,
+ // });
}
for (const backupExchangeDetails of backupBlob.exchange_details) {
diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts
index 7a8b78b53..e96beb5b2 100644
--- a/packages/taler-wallet-core/src/operations/common.ts
+++ b/packages/taler-wallet-core/src/operations/common.ts
@@ -30,6 +30,7 @@ import {
ExchangeEntryStatus,
ExchangeListItem,
ExchangeTosStatus,
+ ExchangeUpdateStatus,
getErrorDetailFromException,
j2s,
Logger,
@@ -47,7 +48,7 @@ import {
WalletStoresV1,
CoinRecord,
ExchangeDetailsRecord,
- ExchangeRecord,
+ ExchangeEntryRecord,
BackupProviderRecord,
DepositGroupRecord,
PeerPullPaymentIncomingRecord,
@@ -59,6 +60,8 @@ import {
RefreshGroupRecord,
RewardRecord,
WithdrawalGroupRecord,
+ ExchangeEntryDbUpdateStatus,
+ ExchangeEntryDbRecordStatus,
} from "../db.js";
import { makeErrorDetail, TalerError } from "@gnu-taler/taler-util";
import { InternalWalletState } from "../internal-wallet-state.js";
@@ -529,16 +532,16 @@ export function getExchangeTosStatus(
exchangeDetails: ExchangeDetailsRecord,
): ExchangeTosStatus {
if (!exchangeDetails.tosAccepted) {
- return ExchangeTosStatus.New;
+ return ExchangeTosStatus.Proposed;
}
if (exchangeDetails.tosAccepted?.etag == exchangeDetails.tosCurrentEtag) {
return ExchangeTosStatus.Accepted;
}
- return ExchangeTosStatus.Changed;
+ return ExchangeTosStatus.Proposed;
}
export function makeExchangeListItem(
- r: ExchangeRecord,
+ r: ExchangeEntryRecord,
exchangeDetails: ExchangeDetailsRecord | undefined,
lastError: TalerErrorDetail | undefined,
): ExchangeListItem {
@@ -547,30 +550,57 @@ export function makeExchangeListItem(
error: lastError,
}
: undefined;
- if (!exchangeDetails) {
- return {
- exchangeBaseUrl: r.baseUrl,
- currency: undefined,
- tosStatus: ExchangeTosStatus.Unknown,
- paytoUris: [],
- exchangeStatus: ExchangeEntryStatus.Unknown,
- permanent: r.permanent,
- ageRestrictionOptions: [],
- lastUpdateErrorInfo,
- };
+
+ let exchangeUpdateStatus: ExchangeUpdateStatus;
+ switch (r.updateStatus) {
+ case ExchangeEntryDbUpdateStatus.Failed:
+ exchangeUpdateStatus = ExchangeUpdateStatus.Failed;
+ break;
+ case ExchangeEntryDbUpdateStatus.Initial:
+ exchangeUpdateStatus = ExchangeUpdateStatus.Initial;
+ break;
+ case ExchangeEntryDbUpdateStatus.InitialUpdate:
+ exchangeUpdateStatus = ExchangeUpdateStatus.InitialUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.OutdatedUpdate:
+ exchangeUpdateStatus = ExchangeUpdateStatus.OutdatedUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.Ready:
+ exchangeUpdateStatus = ExchangeUpdateStatus.Ready;
+ break;
+ case ExchangeEntryDbUpdateStatus.ReadyUpdate:
+ exchangeUpdateStatus = ExchangeUpdateStatus.ReadyUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.Suspended:
+ exchangeUpdateStatus = ExchangeUpdateStatus.Suspended;
+ break;
+ }
+
+ let exchangeEntryStatus: ExchangeEntryStatus;
+ switch (r.entryStatus) {
+ case ExchangeEntryDbRecordStatus.Ephemeral:
+ exchangeEntryStatus = ExchangeEntryStatus.Ephemeral;
+ break;
+ case ExchangeEntryDbRecordStatus.Preset:
+ exchangeEntryStatus = ExchangeEntryStatus.Preset;
+ break;
+ case ExchangeEntryDbRecordStatus.Used:
+ exchangeEntryStatus = ExchangeEntryStatus.Used;
+ break;
}
- let exchangeStatus;
- exchangeStatus = ExchangeEntryStatus.Ok;
+
return {
exchangeBaseUrl: r.baseUrl,
- currency: exchangeDetails.currency,
- tosStatus: getExchangeTosStatus(exchangeDetails),
- paytoUris: exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri),
- exchangeStatus,
- permanent: r.permanent,
- ageRestrictionOptions: exchangeDetails.ageMask
+ currency: exchangeDetails?.currency,
+ exchangeUpdateStatus,
+ exchangeEntryStatus,
+ tosStatus: exchangeDetails
+ ? getExchangeTosStatus(exchangeDetails)
+ : ExchangeTosStatus.Pending,
+ ageRestrictionOptions: exchangeDetails?.ageMask
? AgeRestriction.getAgeGroupsFromMask(exchangeDetails.ageMask)
: [],
+ paytoUris: exchangeDetails?.wireInfo.accounts.map((x) => x.payto_uri) ?? [],
lastUpdateErrorInfo,
};
}
@@ -892,13 +922,13 @@ export namespace TaskIdentifiers {
export function forWithdrawal(wg: WithdrawalGroupRecord): TaskId {
return `${PendingTaskType.Withdraw}:${wg.withdrawalGroupId}` as TaskId;
}
- export function forExchangeUpdate(exch: ExchangeRecord): TaskId {
+ export function forExchangeUpdate(exch: ExchangeEntryRecord): TaskId {
return `${PendingTaskType.ExchangeUpdate}:${exch.baseUrl}` as TaskId;
}
export function forExchangeUpdateFromUrl(exchBaseUrl: string): TaskId {
return `${PendingTaskType.ExchangeUpdate}:${exchBaseUrl}` as TaskId;
}
- export function forExchangeCheckRefresh(exch: ExchangeRecord): TaskId {
+ export function forExchangeCheckRefresh(exch: ExchangeEntryRecord): TaskId {
return `${PendingTaskType.ExchangeCheckRefresh}:${exch.baseUrl}` as TaskId;
}
export function forTipPickup(tipRecord: RewardRecord): TaskId {
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts
index c6b46e360..311a71a6e 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -32,6 +32,7 @@ import {
encodeCrock,
ExchangeAuditor,
ExchangeDenomination,
+ ExchangeEntryStatus,
ExchangeGlobalFees,
ExchangeSignKeyJson,
ExchangeWireJson,
@@ -66,10 +67,15 @@ import {
DenominationRecord,
DenominationVerificationStatus,
ExchangeDetailsRecord,
- ExchangeRecord,
+ ExchangeEntryRecord,
WalletStoresV1,
} from "../db.js";
-import { isWithdrawableDenom } from "../index.js";
+import {
+ ExchangeEntryDbRecordStatus,
+ ExchangeEntryDbUpdateStatus,
+ isWithdrawableDenom,
+ WalletDbReadWriteTransaction,
+} from "../index.js";
import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js";
import { checkDbInvariant } from "../util/invariants.js";
import {
@@ -326,6 +332,26 @@ export async function downloadExchangeInfo(
};
}
+export async function addPresetExchangeEntry(
+ tx: WalletDbReadWriteTransaction<"exchanges">,
+ exchangeBaseUrl: string,
+): Promise<void> {
+ let exchange = await tx.exchanges.get(exchangeBaseUrl);
+ if (!exchange) {
+ const r: ExchangeEntryRecord = {
+ entryStatus: ExchangeEntryDbRecordStatus.Preset,
+ updateStatus: ExchangeEntryDbUpdateStatus.Initial,
+ baseUrl: exchangeBaseUrl,
+ detailsPointer: undefined,
+ lastUpdate: undefined,
+ lastKeysEtag: undefined,
+ nextRefreshCheckStampMs: AbsoluteTime.getStampMsNever(),
+ nextUpdateStampMs: AbsoluteTime.getStampMsNever(),
+ };
+ await tx.exchanges.put(r);
+ }
+}
+
export async function provideExchangeRecordInTx(
ws: InternalWalletState,
tx: GetReadWriteAccess<{
@@ -335,20 +361,20 @@ export async function provideExchangeRecordInTx(
baseUrl: string,
now: AbsoluteTime,
): Promise<{
- exchange: ExchangeRecord;
+ exchange: ExchangeEntryRecord;
exchangeDetails: ExchangeDetailsRecord | undefined;
}> {
let exchange = await tx.exchanges.get(baseUrl);
if (!exchange) {
- const r: ExchangeRecord = {
- permanent: true,
+ const r: ExchangeEntryRecord = {
+ entryStatus: ExchangeEntryDbRecordStatus.Ephemeral,
+ updateStatus: ExchangeEntryDbUpdateStatus.InitialUpdate,
baseUrl: baseUrl,
detailsPointer: undefined,
lastUpdate: undefined,
- nextUpdate: AbsoluteTime.toPreciseTimestamp(now),
- nextRefreshCheck: AbsoluteTime.toPreciseTimestamp(now),
+ nextUpdateStampMs: AbsoluteTime.getStampMsNever(),
+ nextRefreshCheckStampMs: AbsoluteTime.getStampMsNever(),
lastKeysEtag: undefined,
- lastWireEtag: undefined,
};
await tx.exchanges.put(r);
exchange = r;
@@ -534,6 +560,10 @@ export async function downloadTosFromAcceptedFormat(
);
}
+/**
+ * FIXME: Split this into two parts: (a) triggering the exchange
+ * to be updated and (b) waiting for the update to finish.
+ */
export async function updateExchangeFromUrl(
ws: InternalWalletState,
baseUrl: string,
@@ -543,7 +573,7 @@ export async function updateExchangeFromUrl(
cancellationToken?: CancellationToken;
} = {},
): Promise<{
- exchange: ExchangeRecord;
+ exchange: ExchangeEntryRecord;
exchangeDetails: ExchangeDetailsRecord;
}> {
const canonUrl = canonicalizeBaseUrl(baseUrl);
@@ -613,7 +643,7 @@ export async function updateExchangeFromUrlHandler(
!forceNow &&
exchangeDetails !== undefined &&
!AbsoluteTime.isExpired(
- AbsoluteTime.fromPreciseTimestamp(exchange.nextUpdate),
+ AbsoluteTime.fromStampMs(exchange.nextUpdateStampMs),
)
) {
logger.trace("using existing exchange info");
@@ -755,11 +785,11 @@ export async function updateExchangeFromUrlHandler(
newDetails.rowId = existingDetails.rowId;
}
r.lastUpdate = TalerPreciseTimestamp.now();
- r.nextUpdate = AbsoluteTime.toPreciseTimestamp(
+ r.nextUpdateStampMs = AbsoluteTime.toStampMs(
AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry),
);
// New denominations might be available.
- r.nextRefreshCheck = TalerPreciseTimestamp.now();
+ r.nextRefreshCheckStampMs = AbsoluteTime.getStampMsNow();
if (detailsPointerChanged) {
r.detailsPointer = {
currency: newDetails.currency,
@@ -948,7 +978,7 @@ export async function getExchangePaytoUri(
*/
export async function getExchangeTrust(
ws: InternalWalletState,
- exchangeInfo: ExchangeRecord,
+ exchangeInfo: ExchangeEntryRecord,
): Promise<TrustInfo> {
let isTrusted = false;
let isAudited = false;
diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts
index 6c6546f83..e37e45c16 100644
--- a/packages/taler-wallet-core/src/operations/pending.ts
+++ b/packages/taler-wallet-core/src/operations/pending.ts
@@ -45,6 +45,7 @@ import {
PeerPushPaymentIncomingRecord,
RefundGroupRecord,
RefundGroupStatus,
+ ExchangeEntryDbUpdateStatus,
} from "../db.js";
import {
PendingOperationsResponse,
@@ -81,19 +82,25 @@ async function gatherExchangePending(
ws: InternalWalletState,
tx: GetReadOnlyAccess<{
exchanges: typeof WalletStoresV1.exchanges;
- exchangeDetails: typeof WalletStoresV1.exchangeDetails;
operationRetries: typeof WalletStoresV1.operationRetries;
}>,
now: AbsoluteTime,
resp: PendingOperationsResponse,
): Promise<void> {
- // FIXME: We should do a range query here based on the update time.
+ // FIXME: We should do a range query here based on the update time
+ // and/or the entry state.
await tx.exchanges.iter().forEachAsync(async (exch) => {
+ switch (exch.updateStatus) {
+ case ExchangeEntryDbUpdateStatus.Initial:
+ case ExchangeEntryDbUpdateStatus.Suspended:
+ case ExchangeEntryDbUpdateStatus.Failed:
+ return;
+ }
const opTag = TaskIdentifiers.forExchangeUpdate(exch);
let opr = await tx.operationRetries.get(opTag);
const timestampDue =
opr?.retryInfo.nextRetry ??
- AbsoluteTime.fromPreciseTimestamp(exch.nextUpdate);
+ AbsoluteTime.fromStampMs(exch.nextUpdateStampMs);
resp.pendingOperations.push({
type: PendingTaskType.ExchangeUpdate,
...getPendingCommon(ws, opTag, timestampDue),
@@ -108,7 +115,7 @@ async function gatherExchangePending(
resp.pendingOperations.push({
type: PendingTaskType.ExchangeCheckRefresh,
...getPendingCommon(ws, opTag, timestampDue),
- timestampDue: AbsoluteTime.fromPreciseTimestamp(exch.nextRefreshCheck),
+ timestampDue: AbsoluteTime.fromStampMs(exch.nextRefreshCheckStampMs),
givesLifeness: false,
exchangeBaseUrl: exch.baseUrl,
});
@@ -184,8 +191,9 @@ export async function iterRecordsForWithdrawal(
WithdrawalGroupStatus.PendingRegisteringBank,
WithdrawalGroupStatus.PendingAml,
);
- withdrawalGroupRecords =
- await tx.withdrawalGroups.indexes.byStatus.getAll(range);
+ withdrawalGroupRecords = await tx.withdrawalGroups.indexes.byStatus.getAll(
+ range,
+ );
} else {
withdrawalGroupRecords =
await tx.withdrawalGroups.indexes.byStatus.getAll();
@@ -344,12 +352,8 @@ export async function iterRecordsForRefund(
f: (r: RefundGroupRecord) => Promise<void>,
): Promise<void> {
if (filter.onlyState === "nonfinal") {
- const keyRange = GlobalIDB.KeyRange.only(
- RefundGroupStatus.Pending
- );
- await tx.refundGroups.indexes.byStatus
- .iter(keyRange)
- .forEachAsync(f);
+ const keyRange = GlobalIDB.KeyRange.only(RefundGroupStatus.Pending);
+ await tx.refundGroups.indexes.byStatus.iter(keyRange).forEachAsync(f);
} else {
await tx.refundGroups.iter().forEachAsync(f);
}
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts
index 72d1a2725..fb356f0fc 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -1190,14 +1190,14 @@ export async function autoRefresh(
`created refresh group for auto-refresh (${res.refreshGroupId})`,
);
}
-// logger.trace(
-// `current wallet time: ${AbsoluteTime.toIsoString(AbsoluteTime.now())}`,
-// );
+ // logger.trace(
+ // `current wallet time: ${AbsoluteTime.toIsoString(AbsoluteTime.now())}`,
+ // );
logger.trace(
`next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`,
);
- exchange.nextRefreshCheck =
- AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
+ exchange.nextRefreshCheckStampMs =
+ AbsoluteTime.toStampMs(minCheckThreshold);
await tx.exchanges.put(exchange);
});
return TaskRunResult.finished();
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 040d191e1..d8ce0a9a2 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -128,6 +128,8 @@ import {
} from "../util/coinSelection.js";
import {
ExchangeDetailsRecord,
+ ExchangeEntryDbRecordStatus,
+ ExchangeEntryDbUpdateStatus,
PendingTaskType,
isWithdrawableDenom,
} from "../index.js";
@@ -2341,10 +2343,6 @@ export async function internalPerformCreateWithdrawalGroup(
}>,
prep: PrepareCreateWithdrawalGroupResult,
): Promise<PerformCreateWithdrawalGroupResult> {
- const transactionId = constructTransactionIdentifier({
- tag: TransactionType.Withdrawal,
- withdrawalGroupId: prep.withdrawalGroup.withdrawalGroupId,
- });
const { withdrawalGroup } = prep;
if (!prep.creationInfo) {
return { withdrawalGroup, transitionInfo: undefined };
@@ -2361,6 +2359,7 @@ export async function internalPerformCreateWithdrawalGroup(
const exchange = await tx.exchanges.get(withdrawalGroup.exchangeBaseUrl);
if (exchange) {
exchange.lastWithdrawal = TalerPreciseTimestamp.now();
+ exchange.entryStatus = ExchangeEntryDbRecordStatus.Used;
await tx.exchanges.put(exchange);
}
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 194894e52..c9ccda20d 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -189,6 +189,7 @@ import {
} from "./operations/deposits.js";
import {
acceptExchangeTermsOfService,
+ addPresetExchangeEntry,
downloadTosFromAcceptedFormat,
getExchangeDetails,
getExchangeRequestTimeout,
@@ -533,6 +534,7 @@ async function fillDefaults(ws: InternalWalletState): Promise<void> {
await tx.auditorTrust.put(c);
}
for (const baseUrl of ws.config.builtin.exchanges) {
+ await addPresetExchangeEntry(tx, baseUrl);
const now = AbsoluteTime.now();
provideExchangeRecordInTx(ws, tx, baseUrl, now);
}
@@ -1688,8 +1690,7 @@ export class Wallet {
public static defaultConfig: Readonly<WalletConfig> = {
builtin: {
- //exchanges: ["https://exchange.demo.taler.net/"],
- exchanges: [],
+ exchanges: ["https://exchange.demo.taler.net/"],
auditors: [
{
currency: "KUDOS",