summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-02-27 15:46:45 +0100
committerFlorian Dold <florian@dold.me>2024-02-27 15:46:45 +0100
commit525a66bcca5ee58814573d3810c0fbc02e937883 (patch)
tree44b14f7b7cd8f61faad73ed0bc7c47aee9f9b2f0
parent11f36c77a1e5722cab5459fbf4ec6752781e84c8 (diff)
downloadwallet-core-525a66bcca5ee58814573d3810c0fbc02e937883.tar.gz
wallet-core-525a66bcca5ee58814573d3810c0fbc02e937883.tar.bz2
wallet-core-525a66bcca5ee58814573d3810c0fbc02e937883.zip
wallet-core: types for observability
-rw-r--r--packages/taler-util/src/index.ts1
-rw-r--r--packages/taler-util/src/notifications.ts73
-rw-r--r--packages/taler-wallet-core/src/wallet.ts17
-rw-r--r--packages/taler-wallet-core/src/withdraw.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/state.ts91
5 files changed, 131 insertions, 56 deletions
diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts
index d9ab60910..28909facb 100644
--- a/packages/taler-util/src/index.ts
+++ b/packages/taler-util/src/index.ts
@@ -43,6 +43,7 @@ export {
setPRNG,
} from "./nacl-fast.js";
export * from "./notifications.js";
+export * from "./observability.js";
export * from "./operation.js";
export * from "./payto.js";
export * from "./promises.js";
diff --git a/packages/taler-util/src/notifications.ts b/packages/taler-util/src/notifications.ts
index d84d3706d..5e335f7ad 100644
--- a/packages/taler-util/src/notifications.ts
+++ b/packages/taler-util/src/notifications.ts
@@ -22,17 +22,18 @@
/**
* Imports.
*/
-import { WithdrawalOperationStatus } from "./index.node.js";
import { TransactionState } from "./transactions-types.js";
import { ExchangeEntryState, TalerErrorDetail } from "./wallet-types.js";
export enum NotificationType {
BalanceChange = "balance-change",
BackupOperationError = "backup-error",
- PendingOperationProcessed = "pending-operation-processed",
TransactionStateTransition = "transaction-state-transition",
ExchangeStateTransition = "exchange-state-transition",
- WithdrawalOperationTransition = "withdrawal-state-transition",
+ TaskProgress = "task-progress",
+ RequestProgress = "request-progress",
+ RequestOnTaskDependency = "request-on-task-dependency",
+ TaskOnTaskDependency = "task-on-task-dependency",
}
export interface ErrorInfoSummary {
@@ -97,26 +98,64 @@ export interface BalanceChangeNotification {
hintTransactionId: string;
}
-export interface BackupOperationErrorNotification {
- type: NotificationType.BackupOperationError;
- error: TalerErrorDetail;
+export interface TaskProgressNotification {
+ type: NotificationType.TaskProgress;
+ taskId: string;
+}
+
+export interface RequestProgressNotification {
+ type: NotificationType.RequestProgress;
+ requestId: string;
+}
+
+export interface RequestOnTaskDependencyNotification {
+ type: NotificationType.RequestOnTaskDependency;
+ parentTaskId: string;
+ childTaskId: string;
}
-export interface PendingOperationProcessedNotification {
- type: NotificationType.PendingOperationProcessed;
- id: string;
- taskResultType: string;
+export interface TaskOnTaskDependencyNotification {
+ type: NotificationType.TaskOnTaskDependency;
+ parentRequestId: string;
+ childTaskId: string;
}
-export interface WithdrawalOperationTransitionNotification {
- type: NotificationType.WithdrawalOperationTransition;
- operationId: string;
- state: WithdrawalOperationStatus;
+
+export type ObservabilityEvent =
+ | {
+ type: "start-http-fetch";
+ url: string;
+ }
+ | {
+ type: "finish-http-fetch";
+ url: string;
+ status: number;
+ }
+ | {
+ type: "start-db-query";
+ name: string;
+ location: string;
+ }
+ | {
+ type: "finish-db-query";
+ name: string;
+ location: string;
+ }
+ | {
+ type: "task-processed";
+ taskResultType: string;
+ };
+
+export interface BackupOperationErrorNotification {
+ type: NotificationType.BackupOperationError;
+ error: TalerErrorDetail;
}
export type WalletNotification =
| BalanceChangeNotification
| BackupOperationErrorNotification
| ExchangeStateTransitionNotification
- | PendingOperationProcessedNotification
- | WithdrawalOperationTransitionNotification
- | TransactionStateTransitionNotification;
+ | TransactionStateTransitionNotification
+ | TaskProgressNotification
+ | RequestProgressNotification
+ | RequestOnTaskDependencyNotification
+ | TaskOnTaskDependencyNotification;
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index bab054f4b..779eefe26 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -27,6 +27,7 @@ import {
AmountString,
Amounts,
AsyncCondition,
+ CancellationToken,
CoinDumpJson,
CoinStatus,
CoreApiResponse,
@@ -41,6 +42,7 @@ import {
ListGlobalCurrencyAuditorsResponse,
ListGlobalCurrencyExchangesResponse,
Logger,
+ ObservabilityContext,
OpenedPromise,
PrepareWithdrawExchangeRequest,
PrepareWithdrawExchangeResponse,
@@ -269,6 +271,21 @@ import {
const logger = new Logger("wallet.ts");
+/**
+ * Execution context for code that is run in the wallet.
+ *
+ * Typically the excecution context is either for a wallet-core
+ * request handler or for a shepherded task.
+ */
+export interface WalletExecutionContext {
+ readonly ws: InternalWalletState;
+ readonly cryptoApi: TalerCryptoInterface;
+ readonly cancellationToken: CancellationToken;
+ readonly http: HttpRequestLibrary;
+ readonly db: DbAccess<typeof WalletStoresV1>;
+ readonly oc: ObservabilityContext;
+}
+
export const EXCHANGE_COINS_LOCK = "exchange-coins-lock";
export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock";
diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts
index 25c1e5129..541525c6b 100644
--- a/packages/taler-wallet-core/src/withdraw.ts
+++ b/packages/taler-wallet-core/src/withdraw.ts
@@ -1975,11 +1975,6 @@ export async function getWithdrawalDetailsForUri(
2,
)}`,
);
- ws.notify({
- type: NotificationType.WithdrawalOperationTransition,
- operationId: info.operationId,
- state: resp.type === "fail" ? info.status : resp.body.status,
- });
ongoingChecks[talerWithdrawUri] = false;
});
}
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 515c5765e..a49ad3d36 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -22,7 +22,7 @@ import {
ExchangeListItem,
NotificationType,
TalerError,
- parseWithdrawExchangeUri
+ parseWithdrawExchangeUri,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -140,8 +140,8 @@ export function useComponentStateFromParams({
confirm: {
onClick: isValid
? pushAlertOnError(async () => {
- onAmountChanged(Amounts.stringify(amount));
- })
+ onAmountChanged(Amounts.stringify(amount));
+ })
: undefined,
},
amount: {
@@ -208,10 +208,17 @@ export function useComponentStateFromURI({
WalletApiOperation.GetWithdrawalDetailsForUri,
{
talerWithdrawUri,
- notifyChangeFromPendingTimeoutMs: 30 * 1000
+ notifyChangeFromPendingTimeoutMs: 30 * 1000,
},
);
- const { amount, defaultExchangeBaseUrl, possibleExchanges, operationId, confirmTransferUrl, status } = uriInfo;
+ const {
+ amount,
+ defaultExchangeBaseUrl,
+ possibleExchanges,
+ operationId,
+ confirmTransferUrl,
+ status,
+ } = uriInfo;
const transaction = await api.wallet.call(
WalletApiOperation.GetWithdrawalTransactionByUri,
{ talerWithdrawUri },
@@ -228,16 +235,16 @@ export function useComponentStateFromURI({
};
});
- const readyToListen = uriInfoHook && !uriInfoHook.hasError
+ const readyToListen = uriInfoHook && !uriInfoHook.hasError;
useEffect(() => {
if (!uriInfoHook) {
return;
}
return api.listener.onUpdateNotification(
- [NotificationType.WithdrawalOperationTransition],
+ [NotificationType.TransactionStateTransition],
() => {
- uriInfoHook.retry()
+ uriInfoHook.retry();
},
);
}, [readyToListen]);
@@ -282,14 +289,14 @@ export function useComponentStateFromURI({
if (uriInfoHook.response.status !== "pending") {
if (uriInfoHook.response.transaction) {
- onSuccess(uriInfoHook.response.transaction.transactionId)
+ onSuccess(uriInfoHook.response.transaction.transactionId);
}
return {
status: "already-completed",
operationState: uriInfoHook.response.status,
confirmTransferUrl: uriInfoHook.response.confirmTransferUrl,
error: undefined,
- }
+ };
}
return useCallback(() => {
@@ -302,7 +309,7 @@ export function useComponentStateFromURI({
exchangeList,
defaultExchange,
);
- }, [])
+ }, []);
}
type ManualOrManagedWithdrawFunction = (
@@ -330,13 +337,18 @@ function exchangeSelectionState(
return selectedExchange;
}
- return useCallback((): State.Success | State.LoadingUriError | State.Loading => {
+ return useCallback(():
+ | State.Success
+ | State.LoadingUriError
+ | State.Loading => {
const { i18n } = useTranslationContext();
const { pushAlertOnError } = useAlertContext();
const [ageRestricted, setAgeRestricted] = useState(0);
const currentExchange = selectedExchange.selected;
- const [selectedCurrency, setSelectedCurrency] = useState<string>(chosenAmount.currency)
+ const [selectedCurrency, setSelectedCurrency] = useState<string>(
+ chosenAmount.currency,
+ );
/**
* With the exchange and amount, ask the wallet the information
* about the withdrawal
@@ -359,7 +371,7 @@ function exchangeSelectionState(
return {
amount: withdrawAmount,
ageRestrictionOptions: info.ageRestrictionOptions,
- accounts: info.withdrawalAccountsList
+ accounts: info.withdrawalAccountsList,
};
}, []);
@@ -424,23 +436,33 @@ function exchangeSelectionState(
//TODO: calculate based on exchange info
const ageRestriction = ageRestrictionEnabled
? {
- list: ageRestrictionOptions,
- value: String(ageRestricted),
- onChange: pushAlertOnError(async (v: string) =>
- setAgeRestricted(parseInt(v, 10)),
- ),
- }
+ list: ageRestrictionOptions,
+ value: String(ageRestricted),
+ onChange: pushAlertOnError(async (v: string) =>
+ setAgeRestricted(parseInt(v, 10)),
+ ),
+ }
: undefined;
- const altCurrencies = amountHook.response.accounts.filter(a => !!a.currencySpecification).map(a => a.currencySpecification!.name)
- const chooseCurrencies = altCurrencies.length === 0 ? [] : [toBeReceived.currency, ...altCurrencies]
- const convAccount = amountHook.response.accounts.find(c => {
- return c.currencySpecification && c.currencySpecification.name === selectedCurrency
- })
- const conversionInfo = !convAccount ? undefined : ({
- spec: convAccount.currencySpecification!,
- amount: Amounts.parseOrThrow(convAccount.transferAmount!)
- })
+ const altCurrencies = amountHook.response.accounts
+ .filter((a) => !!a.currencySpecification)
+ .map((a) => a.currencySpecification!.name);
+ const chooseCurrencies =
+ altCurrencies.length === 0
+ ? []
+ : [toBeReceived.currency, ...altCurrencies];
+ const convAccount = amountHook.response.accounts.find((c) => {
+ return (
+ c.currencySpecification &&
+ c.currencySpecification.name === selectedCurrency
+ );
+ });
+ const conversionInfo = !convAccount
+ ? undefined
+ : {
+ spec: convAccount.currencySpecification!,
+ amount: Amounts.parseOrThrow(convAccount.transferAmount!),
+ };
return {
status: "success",
@@ -450,17 +472,18 @@ function exchangeSelectionState(
toBeReceived,
chooseCurrencies,
selectedCurrency,
- changeCurrency: (s) => { setSelectedCurrency(s) },
+ changeCurrency: (s) => {
+ setSelectedCurrency(s);
+ },
conversionInfo,
withdrawalFee,
chosenAmount,
talerWithdrawUri,
ageRestriction,
doWithdrawal: {
- onClick:
- doingWithdraw
- ? undefined
- : pushAlertOnError(doWithdrawAndCheckError),
+ onClick: doingWithdraw
+ ? undefined
+ : pushAlertOnError(doWithdrawAndCheckError),
},
cancel,
};