aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/wallet.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-06-28 14:56:59 +0200
committerFlorian Dold <florian@dold.me>2024-06-29 14:16:45 +0200
commit698be4c436240e97f66a66c3af23192033c818b3 (patch)
tree169e181b4491fd9ead42167d487ebc5c67130533 /packages/taler-wallet-core/src/wallet.ts
parenta8861c9deb9521194f513688af6115cf66e511d7 (diff)
downloadwallet-core-698be4c436240e97f66a66c3af23192033c818b3.tar.xz
wallet-core: request handler refactoring WIP
Diffstat (limited to 'packages/taler-wallet-core/src/wallet.ts')
-rw-r--r--packages/taler-wallet-core/src/wallet.ts258
1 files changed, 178 insertions, 80 deletions
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index b6167be12..c2ec17f48 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -26,6 +26,7 @@ import { IDBDatabase, IDBFactory } from "@gnu-taler/idb-bridge";
import {
AbsoluteTime,
ActiveTask,
+ AddExchangeRequest,
AmountJson,
AmountString,
Amounts,
@@ -40,7 +41,10 @@ import {
ExchangesShortListResponse,
GetCurrencySpecificationRequest,
GetCurrencySpecificationResponse,
+ InitRequest,
InitResponse,
+ IntegrationTestArgs,
+ IntegrationTestV2Args,
KnownBankAccounts,
KnownBankAccountsInfo,
ListGlobalCurrencyAuditorsResponse,
@@ -55,6 +59,8 @@ import {
PrepareWithdrawExchangeRequest,
PrepareWithdrawExchangeResponse,
RecoverStoredBackupRequest,
+ SharePaymentRequest,
+ SharePaymentResult,
StoredBackupList,
TalerBankIntegrationHttpClient,
TalerError,
@@ -62,15 +68,19 @@ import {
TalerProtocolTimestamp,
TalerUriAction,
TestingGetDenomStatsResponse,
+ TestingListTasksForTransactionRequest,
TestingListTasksForTransactionsResponse,
TestingWaitTransactionRequest,
TimerAPI,
TimerGroup,
TransactionType,
+ UpdateExchangeEntryRequest,
+ ValidateIbanRequest,
ValidateIbanResponse,
WalletCoreVersion,
WalletNotification,
WalletRunConfig,
+ WithdrawTestBalanceRequest,
canonicalizeBaseUrl,
checkDbInvariant,
codecForAbortTransaction,
@@ -308,6 +318,7 @@ import {
WALLET_MERCHANT_PROTOCOL_VERSION,
} from "./versions.js";
import {
+ EmptyObject,
WalletApiOperation,
WalletCoreApiClient,
WalletCoreResponseType,
@@ -694,6 +705,158 @@ export interface PendingOperationsResponse {
pendingOperations: any[];
}
+async function handleRetryPendingNow(
+ wex: WalletExecutionContext,
+): Promise<EmptyObject> {
+ logger.error("retryPendingNow currently not implemented");
+ return {};
+}
+
+async function handleSharePayment(
+ wex: WalletExecutionContext,
+ req: SharePaymentRequest,
+): Promise<SharePaymentResult> {
+ return await sharePayment(wex, req.merchantBaseUrl, req.orderId);
+}
+
+async function handleDeleteStoredBackup(
+ wex: WalletExecutionContext,
+ req: DeleteStoredBackupRequest,
+): Promise<EmptyObject> {
+ await deleteStoredBackup(wex, req);
+ return {};
+}
+
+async function handleRecoverStoredBackup(
+ wex: WalletExecutionContext,
+ req: RecoverStoredBackupRequest,
+): Promise<EmptyObject> {
+ await recoverStoredBackup(wex, req);
+ return {};
+}
+
+async function handleSetWalletRunConfig(
+ wex: WalletExecutionContext,
+ req: InitRequest,
+) {
+ if (logger.shouldLogTrace()) {
+ const initType = wex.ws.initCalled
+ ? "repeat initialization"
+ : "first initialization";
+ logger.trace(`init request (${initType}): ${j2s(req)}`);
+ }
+
+ // Write to the DB to make sure that we're failing early in
+ // case the DB is not writeable.
+ try {
+ await wex.db.runReadWriteTx({ storeNames: ["config"] }, async (tx) => {
+ tx.config.put({
+ key: ConfigRecordKey.LastInitInfo,
+ value: timestampProtocolToDb(TalerProtocolTimestamp.now()),
+ });
+ });
+ } catch (e) {
+ logger.error("error writing to database during initialization");
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_DB_UNAVAILABLE, {
+ innerError: getErrorDetailFromException(e),
+ });
+ }
+ wex.ws.initWithConfig(applyRunConfigDefaults(req.config));
+
+ if (wex.ws.config.testing.skipDefaults) {
+ logger.trace("skipping defaults");
+ } else {
+ logger.trace("filling defaults");
+ await fillDefaults(wex);
+ }
+ const resp: InitResponse = {
+ versionInfo: handleGetVersion(wex),
+ };
+
+ if (req.config?.lazyTaskLoop) {
+ logger.trace("lazily starting task loop");
+ } else {
+ await wex.taskScheduler.ensureRunning();
+ }
+
+ wex.ws.initCalled = true;
+ return resp;
+}
+
+async function handleWithdrawTestkudos(wex: WalletExecutionContext) {
+ await withdrawTestBalance(wex, {
+ amount: "TESTKUDOS:10" as AmountString,
+ corebankApiBaseUrl: "https://bank.test.taler.net/",
+ exchangeBaseUrl: "https://exchange.test.taler.net/",
+ });
+ // FIXME: Is this correct?
+ return {
+ versionInfo: handleGetVersion(wex),
+ };
+}
+
+async function handleWithdrawTestBalance(
+ wex: WalletExecutionContext,
+ req: WithdrawTestBalanceRequest,
+): Promise<EmptyObject> {
+ await withdrawTestBalance(wex, req);
+ return {};
+}
+
+async function handleTestingListTasksForTransaction(
+ wex: WalletExecutionContext,
+ req: TestingListTasksForTransactionRequest,
+): Promise<TestingListTasksForTransactionsResponse> {
+ return {
+ taskIdList: listTaskForTransactionId(req.transactionId),
+ };
+}
+
+async function handleRunIntegrationTest(
+ wex: WalletExecutionContext,
+ req: IntegrationTestArgs,
+): Promise<EmptyObject> {
+ await runIntegrationTest(wex, req);
+ return {};
+}
+
+async function handleRunIntegrationTestV2(
+ wex: WalletExecutionContext,
+ req: IntegrationTestV2Args,
+): Promise<EmptyObject> {
+ await runIntegrationTest2(wex, req);
+ return {};
+}
+
+async function handleValidateIban(
+ wex: WalletExecutionContext,
+ req: ValidateIbanRequest,
+): Promise<ValidateIbanResponse> {
+ const valRes = validateIban(req.iban);
+ const resp: ValidateIbanResponse = {
+ valid: valRes.type === "valid",
+ };
+ return resp;
+}
+
+async function handleAddExchange(
+ wex: WalletExecutionContext,
+ req: AddExchangeRequest,
+): Promise<EmptyObject> {
+ await fetchFreshExchange(wex, req.exchangeBaseUrl, {});
+ return {};
+}
+
+async function handleUpdateExchangeEntry(
+ wex: WalletExecutionContext,
+ req: UpdateExchangeEntryRequest,
+): Promise<EmptyObject> {
+ await fetchFreshExchange(wex, req.exchangeBaseUrl, {
+ forceUpdate: !!req.force,
+ });
+ return {};
+}
+
/**
* Implementation of the "wallet-core" API.
*/
@@ -712,105 +875,45 @@ async function dispatchRequestInternal(
// definitions we already have?
switch (operation) {
case WalletApiOperation.CreateStoredBackup:
- return createStoredBackup(wex);
+ return await createStoredBackup(wex);
case WalletApiOperation.DeleteStoredBackup: {
const req = codecForDeleteStoredBackupRequest().decode(payload);
- await deleteStoredBackup(wex, req);
- return {};
+ return await handleDeleteStoredBackup(wex, req);
}
case WalletApiOperation.ListStoredBackups:
return listStoredBackups(wex);
case WalletApiOperation.RecoverStoredBackup: {
const req = codecForRecoverStoredBackupRequest().decode(payload);
- await recoverStoredBackup(wex, req);
- return {};
+ return await handleRecoverStoredBackup(wex, req);
}
case WalletApiOperation.SetWalletRunConfig:
case WalletApiOperation.InitWallet: {
const req = codecForInitRequest().decode(payload);
-
- if (logger.shouldLogTrace()) {
- const initType = wex.ws.initCalled
- ? "repeat initialization"
- : "first initialization";
- logger.trace(`init request (${initType}): ${j2s(req)}`);
- }
-
- // Write to the DB to make sure that we're failing early in
- // case the DB is not writeable.
- try {
- await wex.db.runReadWriteTx({ storeNames: ["config"] }, async (tx) => {
- tx.config.put({
- key: ConfigRecordKey.LastInitInfo,
- value: timestampProtocolToDb(TalerProtocolTimestamp.now()),
- });
- });
- } catch (e) {
- logger.error("error writing to database during initialization");
- throw TalerError.fromDetail(TalerErrorCode.WALLET_DB_UNAVAILABLE, {
- innerError: getErrorDetailFromException(e),
- });
- }
- wex.ws.initWithConfig(applyRunConfigDefaults(req.config));
-
- if (wex.ws.config.testing.skipDefaults) {
- logger.trace("skipping defaults");
- } else {
- logger.trace("filling defaults");
- await fillDefaults(wex);
- }
- const resp: InitResponse = {
- versionInfo: handleGetVersion(wex),
- };
-
- if (req.config?.lazyTaskLoop) {
- logger.trace("lazily starting task loop");
- } else {
- await wex.taskScheduler.ensureRunning();
- }
-
- wex.ws.initCalled = true;
- return resp;
+ return await handleSetWalletRunConfig(wex, req);
}
case WalletApiOperation.WithdrawTestkudos: {
- await withdrawTestBalance(wex, {
- amount: "TESTKUDOS:10" as AmountString,
- corebankApiBaseUrl: "https://bank.test.taler.net/",
- exchangeBaseUrl: "https://exchange.test.taler.net/",
- });
- return {
- versionInfo: handleGetVersion(wex),
- };
+ return await handleWithdrawTestkudos(wex);
}
case WalletApiOperation.WithdrawTestBalance: {
const req = codecForWithdrawTestBalance().decode(payload);
- await withdrawTestBalance(wex, req);
- return {};
+ return await handleWithdrawTestBalance(wex, req);
}
case WalletApiOperation.TestingListTaskForTransaction: {
const req =
codecForTestingListTasksForTransactionRequest().decode(payload);
- return {
- taskIdList: listTaskForTransactionId(req.transactionId),
- } satisfies TestingListTasksForTransactionsResponse;
+ return await handleTestingListTasksForTransaction(wex, req);
}
case WalletApiOperation.RunIntegrationTest: {
const req = codecForIntegrationTestArgs().decode(payload);
- await runIntegrationTest(wex, req);
- return {};
+ return await handleRunIntegrationTest(wex, req);
}
case WalletApiOperation.RunIntegrationTestV2: {
const req = codecForIntegrationTestV2Args().decode(payload);
- await runIntegrationTest2(wex, req);
- return {};
+ return await handleRunIntegrationTestV2(wex, req);
}
case WalletApiOperation.ValidateIban: {
const req = codecForValidateIbanRequest().decode(payload);
- const valRes = validateIban(req.iban);
- const resp: ValidateIbanResponse = {
- valid: valRes.type === "valid",
- };
- return resp;
+ return handleValidateIban(wex, req);
}
case WalletApiOperation.TestPay: {
const req = codecForTestPayArgs().decode(payload);
@@ -830,18 +933,14 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.AddExchange: {
const req = codecForAddExchangeRequest().decode(payload);
- await fetchFreshExchange(wex, req.exchangeBaseUrl, {});
- return {};
+ return await handleAddExchange(wex, req);
}
case WalletApiOperation.TestingPing: {
return {};
}
case WalletApiOperation.UpdateExchangeEntry: {
const req = codecForUpdateExchangeEntryRequest().decode(payload);
- await fetchFreshExchange(wex, req.exchangeBaseUrl, {
- forceUpdate: !!req.force,
- });
- return {};
+ return await handleUpdateExchangeEntry(wex, req);
}
case WalletApiOperation.TestingGetDenomStats: {
const req = codecForTestingGetDenomStatsRequest().decode(payload);
@@ -1042,16 +1141,15 @@ async function dispatchRequestInternal(
throw Error("transactionId missing");
}
case WalletApiOperation.RetryPendingNow: {
- logger.error("retryPendingNow currently not implemented");
- return {};
+ return handleRetryPendingNow(wex);
}
case WalletApiOperation.SharePayment: {
const req = codecForSharePaymentRequest().decode(payload);
- return await sharePayment(wex, req.merchantBaseUrl, req.orderId);
+ return await handleSharePayment(wex, req);
}
case WalletApiOperation.PrepareWithdrawExchange: {
const req = codecForPrepareWithdrawExchangeRequest().decode(payload);
- return handlePrepareWithdrawExchange(wex, req);
+ return await handlePrepareWithdrawExchange(wex, req);
}
case WalletApiOperation.CheckPayForTemplate: {
const req = codecForCheckPayTemplateRequest().decode(payload);