summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-04-08 22:29:51 +0200
committerFlorian Dold <florian@dold.me>2024-04-08 22:29:51 +0200
commit859d5c56c7a5b26e741254d6d1e9c5731a787ae1 (patch)
tree55a45b686974318b0a8bb63f307ade0830e7c0e3 /packages/taler-wallet-core/src
parent30dea85f1e2410f974f8c16e4e53d4ba1290442d (diff)
downloadwallet-core-859d5c56c7a5b26e741254d6d1e9c5731a787ae1.tar.gz
wallet-core-859d5c56c7a5b26e741254d6d1e9c5731a787ae1.tar.bz2
wallet-core-859d5c56c7a5b26e741254d6d1e9c5731a787ae1.zip
wallet-core: support cancellation for getWithdrawalDetailsForAmount
Diffstat (limited to 'packages/taler-wallet-core/src')
-rw-r--r--packages/taler-wallet-core/src/wallet.ts35
-rw-r--r--packages/taler-wallet-core/src/withdraw.ts60
2 files changed, 67 insertions, 28 deletions
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 223272745..d8361c6e4 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -71,7 +71,6 @@ import {
WalletCoreVersion,
WalletNotification,
WalletRunConfig,
- WithdrawalDetailsForAmount,
checkDbInvariant,
codecForAbortTransaction,
codecForAcceptBankIntegratedWithdrawalRequest,
@@ -291,7 +290,7 @@ import {
import {
acceptWithdrawalFromUri,
createManualWithdrawal,
- getExchangeWithdrawalInfo,
+ getWithdrawalDetailsForAmount,
getWithdrawalDetailsForUri,
} from "./withdraw.js";
@@ -668,6 +667,7 @@ export interface PendingOperationsResponse {
*/
async function dispatchRequestInternal<Op extends WalletApiOperation>(
wex: WalletExecutionContext,
+ cts: CancellationToken.Source,
operation: WalletApiOperation,
payload: unknown,
): Promise<WalletCoreResponseType<typeof operation>> {
@@ -893,27 +893,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
case WalletApiOperation.GetWithdrawalDetailsForAmount: {
const req =
codecForGetWithdrawalDetailsForAmountRequest().decode(payload);
- const wi = await getExchangeWithdrawalInfo(
- wex,
- req.exchangeBaseUrl,
- Amounts.parseOrThrow(req.amount),
- req.restrictAge,
- );
- let numCoins = 0;
- for (const x of wi.selectedDenoms.selectedDenoms) {
- numCoins += x.count;
- }
- const resp: WithdrawalDetailsForAmount = {
- amountRaw: req.amount,
- amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
- paytoUris: wi.exchangePaytoUris,
- tosAccepted: wi.termsOfServiceAccepted,
- ageRestrictionOptions: wi.ageRestrictionOptions,
- withdrawalAccountsList: wi.exchangeCreditAccountDetails,
- numCoins,
- // FIXME: Once we have proper scope info support, return correct info here.
- scopeInfo: wi.scopeInfo,
- };
+ const resp = await getWithdrawalDetailsForAmount(wex, cts, req);
return resp;
}
case WalletApiOperation.GetBalances: {
@@ -1522,6 +1502,8 @@ async function handleCoreApiRequest(
let wex: WalletExecutionContext;
let oc: ObservabilityContext;
+ const cts = CancellationToken.create();
+
if (ws.initCalled && ws.config.testing.emitObservabilityEvents) {
oc = {
observe(evt) {
@@ -1534,12 +1516,12 @@ async function handleCoreApiRequest(
},
};
- wex = getObservedWalletExecutionContext(ws, CancellationToken.CONTINUE, oc);
+ wex = getObservedWalletExecutionContext(ws, cts.token, oc);
} else {
oc = {
observe(evt) {},
};
- wex = getNormalWalletExecutionContext(ws, CancellationToken.CONTINUE, oc);
+ wex = getNormalWalletExecutionContext(ws, cts.token, oc);
}
try {
@@ -1550,6 +1532,7 @@ async function handleCoreApiRequest(
});
const result = await dispatchRequestInternal(
wex,
+ cts,
operation as any,
payload,
);
@@ -1772,6 +1755,8 @@ export class InternalWalletState {
devExperimentState: DevExperimentState = {};
+ clientCancellationMap: Map<string, CancellationToken.Source> = new Map();
+
initWithConfig(newConfig: WalletRunConfig): void {
this._config = newConfig;
diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts
index 960ffa525..68ff9d494 100644
--- a/packages/taler-wallet-core/src/withdraw.ts
+++ b/packages/taler-wallet-core/src/withdraw.ts
@@ -49,6 +49,7 @@ import {
ExchangeWithdrawResponse,
ExchangeWithdrawalDetails,
ForcedDenomSel,
+ GetWithdrawalDetailsForAmountRequest,
HttpStatusCode,
LibtoolVersion,
Logger,
@@ -69,6 +70,7 @@ import {
UnblindedSignature,
WalletNotification,
WithdrawUriInfoResponse,
+ WithdrawalDetailsForAmount,
WithdrawalExchangeAccountDetails,
WithdrawalType,
addPaytoQueryParams,
@@ -1273,7 +1275,6 @@ export async function updateWithdrawalDenoms(
wex: WalletExecutionContext,
exchangeBaseUrl: string,
): Promise<void> {
-
logger.trace(
`updating denominations used for withdrawal for ${exchangeBaseUrl}`,
);
@@ -1931,7 +1932,9 @@ export async function getExchangeWithdrawalInfo(
ageRestricted: number | undefined,
): Promise<ExchangeWithdrawalDetails> {
logger.trace("updating exchange");
- const exchange = await fetchFreshExchange(wex, exchangeBaseUrl);
+ const exchange = await fetchFreshExchange(wex, exchangeBaseUrl, {
+ cancellationToken: wex.cancellationToken,
+ });
if (exchange.currency != instructedAmount.currency) {
// Specifying the amount in the conversion input currency is not yet supported.
@@ -1947,7 +1950,7 @@ export async function getExchangeWithdrawalInfo(
exchange,
instructedAmount,
},
- CancellationToken.CONTINUE,
+ wex.cancellationToken,
);
logger.trace("updating withdrawal denoms");
@@ -3152,3 +3155,54 @@ async function internalWaitWithdrawalFinal(
flag.reset();
}
}
+
+export async function getWithdrawalDetailsForAmount(
+ wex: WalletExecutionContext,
+ cts: CancellationToken.Source,
+ req: GetWithdrawalDetailsForAmountRequest,
+): Promise<WithdrawalDetailsForAmount> {
+ const clientCancelKey = req.clientCancellationId
+ ? `ccid:getWithdrawalDetailsForAmount:${req.clientCancellationId}`
+ : undefined;
+ if (clientCancelKey) {
+ const prevCts = wex.ws.clientCancellationMap.get(clientCancelKey);
+ if (prevCts) {
+ prevCts.cancel();
+ }
+ wex.ws.clientCancellationMap.set(clientCancelKey, cts);
+ }
+ try {
+ return internalGetWithdrawalDetailsForAmount(wex, req);
+ } finally {
+ if (clientCancelKey && !cts.token.isCancelled) {
+ wex.ws.clientCancellationMap.delete(clientCancelKey);
+ }
+ }
+}
+
+async function internalGetWithdrawalDetailsForAmount(
+ wex: WalletExecutionContext,
+ req: GetWithdrawalDetailsForAmountRequest,
+): Promise<WithdrawalDetailsForAmount> {
+ const wi = await getExchangeWithdrawalInfo(
+ wex,
+ req.exchangeBaseUrl,
+ Amounts.parseOrThrow(req.amount),
+ req.restrictAge,
+ );
+ let numCoins = 0;
+ for (const x of wi.selectedDenoms.selectedDenoms) {
+ numCoins += x.count;
+ }
+ const resp: WithdrawalDetailsForAmount = {
+ amountRaw: req.amount,
+ amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
+ paytoUris: wi.exchangePaytoUris,
+ tosAccepted: wi.termsOfServiceAccepted,
+ ageRestrictionOptions: wi.ageRestrictionOptions,
+ withdrawalAccountsList: wi.exchangeCreditAccountDetails,
+ numCoins,
+ scopeInfo: wi.scopeInfo,
+ };
+ return resp;
+}