commit 7535b45024251cfc23489f48b9b2bc7ff8a1cf34
parent c043647f7a83fe1d2e05107924b3fea3a7ff7838
Author: Florian Dold <florian@dold.me>
Date: Wed, 15 Jul 2026 15:41:26 +0200
wallet-core: add causeHint to exchange notification
Diffstat:
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/packages/taler-util/src/notifications.ts b/packages/taler-util/src/notifications.ts
@@ -105,6 +105,13 @@ export interface ExchangeStateTransitionNotification {
exchangeBaseUrl: string;
/**
+ * A hint as to why the transition happened.
+ *
+ * Should not be relied upon by clients.
+ */
+ causeHint: string | undefined;
+
+ /**
* If missing, the notification means that
* the exchange entry is newly created.
*/
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -87,7 +87,6 @@ import {
TransactionType,
URL,
WalletKycRequest,
- WalletNotification,
WireFee,
WireFeeMap,
WireInfo,
@@ -618,6 +617,7 @@ export async function acceptExchangeTermsOfService(
wex.ws.exchangeCache.clear();
tx.notify({
type: NotificationType.ExchangeStateTransition,
+ causeHint: "tos-accepted",
exchangeBaseUrl,
newExchangeState: newExchangeState,
oldExchangeState: oldExchangeState,
@@ -647,6 +647,7 @@ export async function forgetExchangeTermsOfService(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "tos-unaccepted",
newExchangeState: newExchangeState,
oldExchangeState: oldExchangeState,
});
@@ -809,6 +810,7 @@ export async function putPresetExchangeEntry(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: exchangeBaseUrl,
+ causeHint: "creation-preset",
// Exchange did not exist yet
oldExchangeState: undefined,
newExchangeState: getExchangeState(r),
@@ -829,7 +831,6 @@ async function provideExchangeRecordInTx(
exchange: ExchangeEntryRecord;
exchangeDetails: ExchangeDetailsRecord | undefined;
}> {
- let notification: WalletNotification | undefined = undefined;
let exchange = await tx.exchanges.get(baseUrl);
if (!exchange) {
const r: ExchangeEntryRecord = {
@@ -858,6 +859,7 @@ async function provideExchangeRecordInTx(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: r.baseUrl,
+ causeHint: "creation",
oldExchangeState: undefined,
newExchangeState: getExchangeState(r),
});
@@ -1217,6 +1219,7 @@ export async function startUpdateExchangeEntry(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "update-started",
newExchangeState: newExchangeState,
oldExchangeState: oldExchangeState,
});
@@ -1688,6 +1691,7 @@ async function handleExchageUpdateIncompatible(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "update-incompatible",
newExchangeState,
oldExchangeState,
});
@@ -2016,6 +2020,7 @@ export async function updateExchangeFromUrlHandler(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "details-incompatible",
newExchangeState: getExchangeState(r),
oldExchangeState,
});
@@ -2258,6 +2263,7 @@ export async function updateExchangeFromUrlHandler(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "update-from-response",
newExchangeState,
oldExchangeState,
});
@@ -2349,6 +2355,7 @@ async function doExchangeAutoRefresh(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "auto-refresh",
newExchangeState: st,
oldExchangeState: st,
});
@@ -2972,6 +2979,7 @@ export async function markExchangeUsed(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
+ causeHint: "mark-used",
newExchangeState: newExchangeState,
oldExchangeState: oldExchangeState,
});
@@ -3190,6 +3198,7 @@ async function purgeExchange(
tx.notify({
type: NotificationType.ExchangeStateTransition,
oldExchangeState,
+ causeHint: "purge",
newExchangeState: undefined,
exchangeBaseUrl,
});
@@ -3705,6 +3714,7 @@ export async function handleStartExchangeWalletKyc(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: exchange.baseUrl,
+ causeHint: "wallet-kyc",
oldExchangeState,
newExchangeState: getExchangeState(exchange),
});
@@ -3831,6 +3841,7 @@ async function handleExchangeKycSuccess(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: exchange.baseUrl,
+ causeHint: "wallet-kyc-success",
oldExchangeState,
newExchangeState: getExchangeState(exchange),
});
@@ -3938,6 +3949,7 @@ async function handleExchangeKycRespLegi(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: exchange.baseUrl,
+ causeHint: "wallet-kyc-resp-legi",
oldExchangeState,
newExchangeState: getExchangeState(exchange),
});
@@ -4365,6 +4377,7 @@ export async function migrateExchange(
tx.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: req.oldExchangeBaseUrl,
+ causeHint: "migration-old",
oldExchangeState: getExchangeState(exch),
newExchangeState: undefined,
});
@@ -4373,6 +4386,7 @@ export async function migrateExchange(
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: req.newExchangeBaseUrl,
oldExchangeState: existingNewExchangeSt,
+ causeHint: "migration-new",
newExchangeState: getExchangeState(exch),
});
});
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts
@@ -966,6 +966,7 @@ async function makeExchangeRetryNotification(
const notif: WalletNotification = {
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl: parsedTaskId.exchangeBaseUrl,
+ causeHint: "shepherd-retry",
oldExchangeState: getExchangeState(rec),
newExchangeState: getExchangeState(rec),
};