diff options
author | Florian Dold <florian@dold.me> | 2024-07-05 14:51:21 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-07-05 14:51:21 +0200 |
commit | 843aefc42b0b02c6e8858adc794447956f45875a (patch) | |
tree | 247ef886923965efe7f33939613981568f3d5ba1 /packages/taler-wallet-core | |
parent | 2365276434728c249b4a06130fb6235f506b891b (diff) |
wallet-core: handlers refactoring
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r-- | packages/taler-wallet-core/src/shepherd.ts | 4 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet-api-types.ts | 9 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 893 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/withdraw.ts | 8 |
4 files changed, 465 insertions, 449 deletions
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts index 434ee8635..c4960bb11 100644 --- a/packages/taler-wallet-core/src/shepherd.ts +++ b/packages/taler-wallet-core/src/shepherd.ts @@ -618,12 +618,12 @@ function getWalletExecutionContextForTask( }, }; - wex = getObservedWalletExecutionContext(ws, cancellationToken, oc); + wex = getObservedWalletExecutionContext(ws, cancellationToken, undefined, oc); } else { oc = { observe(evt) {}, }; - wex = getNormalWalletExecutionContext(ws, cancellationToken, oc); + wex = getNormalWalletExecutionContext(ws, cancellationToken, undefined, oc); } return wex; } diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 12abb6469..aa68c6e2a 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -29,6 +29,8 @@ import { AcceptExchangeTosRequest, AcceptManualWithdrawalRequest, AcceptManualWithdrawalResult, + AcceptPeerPullPaymentResponse, + AcceptPeerPushPaymentResponse, AcceptWithdrawalResponse, AddExchangeRequest, AddGlobalCurrencyAuditorRequest, @@ -133,6 +135,7 @@ import { TestPayResult, TestingGetDenomStatsRequest, TestingGetDenomStatsResponse, + TestingGetReserveHistoryRequest, TestingSetTimetravelRequest, TestingWaitTransactionRequest, Transaction, @@ -944,7 +947,7 @@ export type PreparePeerPushCreditOp = { export type ConfirmPeerPushCreditOp = { op: WalletApiOperation.ConfirmPeerPushCredit; request: ConfirmPeerPushCreditRequest; - response: EmptyObject; + response: AcceptPeerPushPaymentResponse; }; /** @@ -980,7 +983,7 @@ export type PreparePeerPullDebitOp = { export type ConfirmPeerPullDebitOp = { op: WalletApiOperation.ConfirmPeerPullDebit; request: ConfirmPeerPullDebitRequest; - response: EmptyObject; + response: AcceptPeerPullPaymentResponse; }; // group: Data Validation @@ -1205,7 +1208,7 @@ export type TestingPingOp = { export type TestingGetReserveHistoryOp = { op: WalletApiOperation.TestingGetReserveHistory; - request: EmptyObject; + request: TestingGetReserveHistoryRequest; response: any; }; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 1f2686cc9..1723e2c81 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -102,9 +102,9 @@ import { TestingGetDenomStatsResponse, TestingGetReserveHistoryRequest, TestingSetTimetravelRequest, - TestingWaitTransactionRequest, TimerAPI, TimerGroup, + TransactionIdStr, TransactionType, TransactionsResponse, UpdateExchangeEntryRequest, @@ -380,6 +380,7 @@ export interface WalletExecutionContext { readonly http: HttpRequestLibrary; readonly db: DbAccess<typeof WalletStoresV1>; readonly oc: ObservabilityContext; + readonly cts: CancellationToken.Source | undefined; readonly taskScheduler: TaskScheduler; } @@ -791,7 +792,7 @@ async function handleSetWalletRunConfig( await fillDefaults(wex); } const resp: InitResponse = { - versionInfo: handleGetVersion(wex), + versionInfo: await handleGetVersion(wex), }; if (req.config?.lazyTaskLoop) { @@ -1383,7 +1384,6 @@ interface HandlerWithValidator<Tag extends WalletApiOperation> { ) => Promise<WalletCoreResponseType<Tag>>; } -// @ts-ignore const handlers: { [T in WalletApiOperation]: HandlerWithValidator<T> } = { [WalletApiOperation.AbortTransaction]: { codec: codecForAbortTransaction(), @@ -1482,477 +1482,487 @@ const handlers: { [T in WalletApiOperation]: HandlerWithValidator<T> } = { codec: codecForAddExchangeRequest(), handler: (wex, req) => getExchangeDetailedInfo(wex, req.exchangeBaseUrl), }, -}; - -/** - * Implementation of the "wallet-core" API. - */ -async function dispatchRequestInternal( - wex: WalletExecutionContext, - cts: CancellationToken.Source, - operation: WalletApiOperation, - payload: unknown, -): Promise<WalletCoreResponseType<typeof operation>> { - if (!wex.ws.initCalled && operation !== WalletApiOperation.InitWallet) { - throw Error( - `wallet must be initialized before running operation ${operation}`, - ); - } - // FIXME: Can we make this more type-safe by using the request/response type - // definitions we already have? - switch (operation) { - case WalletApiOperation.CreateStoredBackup: - return await handleCreateStoredBackup(wex, {}); - case WalletApiOperation.DeleteStoredBackup: { - const req = codecForDeleteStoredBackupRequest().decode(payload); - return await handleDeleteStoredBackup(wex, req); - } - case WalletApiOperation.ListStoredBackups: - return listStoredBackups(wex); - case WalletApiOperation.RecoverStoredBackup: { - const req = codecForRecoverStoredBackupRequest().decode(payload); - return await handleRecoverStoredBackup(wex, req); - } - case WalletApiOperation.SetWalletRunConfig: - case WalletApiOperation.InitWallet: { - const req = codecForInitRequest().decode(payload); - return await handleSetWalletRunConfig(wex, req); - } - case WalletApiOperation.WithdrawTestkudos: { - return await handleWithdrawTestkudos(wex); - } - case WalletApiOperation.WithdrawTestBalance: { - const req = codecForWithdrawTestBalance().decode(payload); - return await handleWithdrawTestBalance(wex, req); - } - case WalletApiOperation.RunIntegrationTest: { - const req = codecForIntegrationTestArgs().decode(payload); - return await handleRunIntegrationTest(wex, req); - } - case WalletApiOperation.RunIntegrationTestV2: { - const req = codecForIntegrationTestV2Args().decode(payload); - return await handleRunIntegrationTestV2(wex, req); - } - case WalletApiOperation.ValidateIban: { - const req = codecForValidateIbanRequest().decode(payload); - return handleValidateIban(wex, req); - } - case WalletApiOperation.TestPay: { - const req = codecForTestPayArgs().decode(payload); - return await testPay(wex, req); - } - case WalletApiOperation.GetTransactions: { - const req = codecForTransactionsRequest().decode(payload); - return await getTransactions(wex, req); - } - case WalletApiOperation.GetTransactionById: { - const req = codecForTransactionByIdRequest().decode(payload); - return await getTransactionById(wex, req); - } - case WalletApiOperation.GetWithdrawalTransactionByUri: { - const req = codecForGetWithdrawalDetailsForUri().decode(payload); - return await getWithdrawalTransactionByUri(wex, req); - } - case WalletApiOperation.AddExchange: { - const req = codecForAddExchangeRequest().decode(payload); - return await handleAddExchange(wex, req); - } - case WalletApiOperation.TestingPing: { + [WalletApiOperation.ListKnownBankAccounts]: { + codec: codecForListKnownBankAccounts(), + handler: (wex, req) => listKnownBankAccounts(wex, req.currency), + }, + [WalletApiOperation.AddKnownBankAccounts]: { + codec: codecForAddKnownBankAccounts(), + handler: handleAddKnownBankAccount, + }, + [WalletApiOperation.ForgetKnownBankAccounts]: { + codec: codecForForgetKnownBankAccounts(), + handler: handleForgetKnownBankAccounts, + }, + [WalletApiOperation.GetWithdrawalDetailsForUri]: { + codec: codecForGetWithdrawalDetailsForUri(), + handler: (wex, req) => + getWithdrawalDetailsForUri(wex, req.talerWithdrawUri), + }, + [WalletApiOperation.TestingGetReserveHistory]: { + codec: codecForTestingGetReserveHistoryRequest(), + handler: handleTestingGetReserveHistory, + }, + [WalletApiOperation.AcceptManualWithdrawal]: { + codec: codecForAcceptManualWithdrawalRequest(), + handler: handleAcceptManualWithdrawal, + }, + [WalletApiOperation.GetWithdrawalDetailsForAmount]: { + codec: codecForGetWithdrawalDetailsForAmountRequest(), + handler: getWithdrawalDetailsForAmount, + }, + [WalletApiOperation.GetBalances]: { + codec: codecForEmptyObject(), + handler: getBalances, + }, + [WalletApiOperation.GetBalanceDetail]: { + codec: codecForGetBalanceDetailRequest(), + handler: getBalanceDetail, + }, + [WalletApiOperation.GetUserAttentionRequests]: { + codec: codecForUserAttentionsRequest(), + handler: getUserAttentions, + }, + [WalletApiOperation.MarkAttentionRequestAsRead]: { + codec: codecForUserAttentionByIdRequest(), + handler: async (wex, req) => { + await markAttentionRequestAsRead(wex, req); return {}; - } - case WalletApiOperation.UpdateExchangeEntry: { - const req = codecForUpdateExchangeEntryRequest().decode(payload); - return await handleUpdateExchangeEntry(wex, req); - } - case WalletApiOperation.TestingGetDenomStats: { - const req = codecForTestingGetDenomStatsRequest().decode(payload); - return handleTestingGetDenomStats(wex, req); - } - case WalletApiOperation.ListExchanges: { - return await listExchanges(wex); - } - case WalletApiOperation.GetExchangeEntryByUrl: { - const req = codecForGetExchangeEntryByUrlRequest().decode(payload); - return lookupExchangeByUri(wex, req); - } - case WalletApiOperation.ListExchangesForScopedCurrency: { - const req = - codecForListExchangesForScopedCurrencyRequest().decode(payload); - return await handleListExchangesForScopedCurrency(wex, req); - } - case WalletApiOperation.GetExchangeDetailedInfo: { - const req = codecForAddExchangeRequest().decode(payload); - return await getExchangeDetailedInfo(wex, req.exchangeBaseUrl); - } - case WalletApiOperation.ListKnownBankAccounts: { - const req = codecForListKnownBankAccounts().decode(payload); - return await listKnownBankAccounts(wex, req.currency); - } - case WalletApiOperation.AddKnownBankAccounts: { - const req = codecForAddKnownBankAccounts().decode(payload); - return await handleAddKnownBankAccount(wex, req); - } - case WalletApiOperation.ForgetKnownBankAccounts: { - const req = codecForForgetKnownBankAccounts().decode(payload); - return await handleForgetKnownBankAccounts(wex, req); - } - case WalletApiOperation.GetWithdrawalDetailsForUri: { - const req = codecForGetWithdrawalDetailsForUri().decode(payload); - return await getWithdrawalDetailsForUri(wex, req.talerWithdrawUri); - } - case WalletApiOperation.TestingGetReserveHistory: { - const req = codecForTestingGetReserveHistoryRequest().decode(payload); - return await handleTestingGetReserveHistory(wex, req); - } - case WalletApiOperation.AcceptManualWithdrawal: { - const req = codecForAcceptManualWithdrawalRequest().decode(payload); - return await handleAcceptManualWithdrawal(wex, req); - } - case WalletApiOperation.GetWithdrawalDetailsForAmount: { - const req = - codecForGetWithdrawalDetailsForAmountRequest().decode(payload); - return await getWithdrawalDetailsForAmount(wex, cts, req); - } - case WalletApiOperation.GetBalances: { - return await getBalances(wex); - } - case WalletApiOperation.GetBalanceDetail: { - const req = codecForGetBalanceDetailRequest().decode(payload); - return await getBalanceDetail(wex, req); - } - case WalletApiOperation.GetUserAttentionRequests: { - const req = codecForUserAttentionsRequest().decode(payload); - return await getUserAttentions(wex, req); - } - case WalletApiOperation.MarkAttentionRequestAsRead: { - const req = codecForUserAttentionByIdRequest().decode(payload); - return await markAttentionRequestAsRead(wex, req); - } - case WalletApiOperation.GetUserAttentionUnreadCount: { - const req = codecForUserAttentionsRequest().decode(payload); - return await getUserAttentionsUnreadCount(wex, req); - } - case WalletApiOperation.SetExchangeTosAccepted: { - const req = codecForAcceptExchangeTosRequest().decode(payload); + }, + }, + [WalletApiOperation.GetUserAttentionUnreadCount]: { + codec: codecForUserAttentionsRequest(), + handler: getUserAttentionsUnreadCount, + }, + [WalletApiOperation.SetExchangeTosAccepted]: { + codec: codecForAcceptExchangeTosRequest(), + handler: async (wex, req) => { await acceptExchangeTermsOfService(wex, req.exchangeBaseUrl); return {}; - } - case WalletApiOperation.SetExchangeTosForgotten: { - const req = codecForAcceptExchangeTosRequest().decode(payload); + }, + }, + [WalletApiOperation.SetExchangeTosForgotten]: { + codec: codecForAcceptExchangeTosRequest(), + handler: async (wex, req) => { await forgetExchangeTermsOfService(wex, req.exchangeBaseUrl); return {}; - } - case WalletApiOperation.AcceptBankIntegratedWithdrawal: { - const req = - codecForAcceptBankIntegratedWithdrawalRequest().decode(payload); - return handleAcceptBankIntegratedWithdrawal(wex, req); - } - case WalletApiOperation.ConfirmWithdrawal: { - const req = codecForConfirmWithdrawalRequestRequest().decode(payload); - return confirmWithdrawal(wex, req); - } - case WalletApiOperation.PrepareBankIntegratedWithdrawal: { - const req = - codecForPrepareBankIntegratedWithdrawalRequest().decode(payload); - return prepareBankIntegratedWithdrawal(wex, req); - } - case WalletApiOperation.GetExchangeTos: { - const req = codecForGetExchangeTosRequest().decode(payload); - return await handleGetExchangeTos(wex, req); - } - case WalletApiOperation.GetContractTermsDetails: { - const req = codecForGetContractTermsDetails().decode(payload); - return handleGetContractTermsDetails(wex, req); - } - case WalletApiOperation.RetryPendingNow: { - return handleRetryPendingNow(wex); - } - case WalletApiOperation.SharePayment: { - const req = codecForSharePaymentRequest().decode(payload); - return await handleSharePayment(wex, req); - } - case WalletApiOperation.PrepareWithdrawExchange: { - const req = codecForPrepareWithdrawExchangeRequest().decode(payload); - return await handlePrepareWithdrawExchange(wex, req); - } - case WalletApiOperation.CheckPayForTemplate: { - const req = codecForCheckPayTemplateRequest().decode(payload); - return await checkPayForTemplate(wex, req); - } - case WalletApiOperation.PreparePayForUri: { - const req = codecForPreparePayRequest().decode(payload); - return await preparePayForUri(wex, req.talerPayUri); - } - case WalletApiOperation.PreparePayForTemplate: { - const req = codecForPreparePayTemplateRequest().decode(payload); - return preparePayForTemplate(wex, req); - } - case WalletApiOperation.GetQrCodesForPayto: { - const req = codecForGetQrCodesForPaytoRequest().decode(payload); - return handleGetQrCodesForPayto(wex, req); - } - case WalletApiOperation.ConfirmPay: { - const req = codecForConfirmPayRequest().decode(payload); - return handleConfirmPay(wex, req); - } - case WalletApiOperation.AbortTransaction: { - const req = codecForAbortTransaction().decode(payload); - return handleAbortTransaction(wex, req); - } - case WalletApiOperation.SuspendTransaction: { - const req = codecForSuspendTransaction().decode(payload); - return handleSuspendTransaction(wex, req); - } - case WalletApiOperation.GetActiveTasks: { - return await handleGetActiveTasks(wex, {}); - } - case WalletApiOperation.FailTransaction: { - const req = codecForFailTransactionRequest().decode(payload); - return await handleFailTransaction(wex, req); - } - case WalletApiOperation.ResumeTransaction: { - const req = codecForResumeTransaction().decode(payload); + }, + }, + [WalletApiOperation.AcceptBankIntegratedWithdrawal]: { + codec: codecForAcceptBankIntegratedWithdrawalRequest(), + handler: handleAcceptBankIntegratedWithdrawal, + }, + [WalletApiOperation.ConfirmWithdrawal]: { + codec: codecForConfirmWithdrawalRequestRequest(), + handler: async (wex, req) => { + await confirmWithdrawal(wex, req); + return {}; + }, + }, + [WalletApiOperation.PrepareBankIntegratedWithdrawal]: { + codec: codecForPrepareBankIntegratedWithdrawalRequest(), + handler: prepareBankIntegratedWithdrawal, + }, + [WalletApiOperation.GetExchangeTos]: { + codec: codecForGetExchangeTosRequest(), + handler: handleGetExchangeTos, + }, + [WalletApiOperation.GetContractTermsDetails]: { + codec: codecForGetContractTermsDetails(), + handler: handleGetContractTermsDetails, + }, + [WalletApiOperation.RetryPendingNow]: { + codec: codecForEmptyObject(), + handler: handleRetryPendingNow, + }, + [WalletApiOperation.SharePayment]: { + codec: codecForSharePaymentRequest(), + handler: handleSharePayment, + }, + [WalletApiOperation.PrepareWithdrawExchange]: { + codec: codecForPrepareWithdrawExchangeRequest(), + handler: handlePrepareWithdrawExchange, + }, + [WalletApiOperation.CheckPayForTemplate]: { + codec: codecForCheckPayTemplateRequest(), + handler: checkPayForTemplate, + }, + [WalletApiOperation.PreparePayForUri]: { + codec: codecForPreparePayRequest(), + handler: (wex, req) => preparePayForUri(wex, req.talerPayUri), + }, + [WalletApiOperation.PreparePayForTemplate]: { + codec: codecForPreparePayTemplateRequest(), + handler: preparePayForTemplate, + }, + [WalletApiOperation.GetQrCodesForPayto]: { + codec: codecForGetQrCodesForPaytoRequest(), + handler: handleGetQrCodesForPayto, + }, + [WalletApiOperation.ConfirmPay]: { + codec: codecForConfirmPayRequest(), + handler: handleConfirmPay, + }, + [WalletApiOperation.SuspendTransaction]: { + codec: codecForSuspendTransaction(), + handler: handleSuspendTransaction, + }, + [WalletApiOperation.GetActiveTasks]: { + codec: codecForEmptyObject(), + handler: handleGetActiveTasks, + }, + [WalletApiOperation.FailTransaction]: { + codec: codecForFailTransactionRequest(), + handler: handleFailTransaction, + }, + [WalletApiOperation.ResumeTransaction]: { + codec: codecForResumeTransaction(), + handler: async (wex, req) => { await resumeTransaction(wex, req.transactionId); return {}; - } - case WalletApiOperation.DumpCoins: { - return await dumpCoins(wex); - } - case WalletApiOperation.SetCoinSuspended: { - const req = codecForSetCoinSuspendedRequest().decode(payload); + }, + }, + [WalletApiOperation.DumpCoins]: { + codec: codecForEmptyObject(), + handler: dumpCoins, + }, + [WalletApiOperation.SetCoinSuspended]: { + codec: codecForSetCoinSuspendedRequest(), + handler: async (wex, req) => { await setCoinSuspended(wex, req.coinPub, req.suspended); return {}; - } - case WalletApiOperation.TestingGetSampleTransactions: - const req = codecForEmptyObject().decode(payload); - return handleTestingGetSampleTransactions(wex, req); - case WalletApiOperation.ForceRefresh: { - const req = codecForForceRefreshRequest().decode(payload); - return await forceRefresh(wex, req); - } - case WalletApiOperation.StartRefundQueryForUri: { - const req = codecForPrepareRefundRequest().decode(payload); - return await startRefundQueryForUri(wex, req.talerRefundUri); - } - case WalletApiOperation.StartRefundQuery: { - const req = codecForStartRefundQueryRequest().decode(payload); - return handleStartRefundQuery(wex, req); - } - case WalletApiOperation.AddBackupProvider: { - const req = codecForAddBackupProviderRequest().decode(payload); - return await addBackupProvider(wex, req); - } - case WalletApiOperation.RunBackupCycle: { - const req = codecForRunBackupCycle().decode(payload); - return handleAddBackupProvider(wex, req); - } - case WalletApiOperation.RemoveBackupProvider: { - const req = codecForRemoveBackupProvider().decode(payload); + }, + }, + [WalletApiOperation.TestingGetSampleTransactions]: { + codec: codecForEmptyObject(), + handler: handleTestingGetSampleTransactions, + }, + [WalletApiOperation.StartRefundQueryForUri]: { + codec: codecForPrepareRefundRequest(), + handler: (wex, req) => startRefundQueryForUri(wex, req.talerRefundUri), + }, + [WalletApiOperation.StartRefundQuery]: { + codec: codecForStartRefundQueryRequest(), + handler: handleStartRefundQuery, + }, + [WalletApiOperation.AddBackupProvider]: { + codec: codecForAddBackupProviderRequest(), + handler: addBackupProvider, + }, + [WalletApiOperation.RunBackupCycle]: { + codec: codecForRunBackupCycle(), + handler: async (wex, req) => { + await runBackupCycle(wex, req); + return {}; + }, + }, + [WalletApiOperation.RemoveBackupProvider]: { + codec: codecForRemoveBackupProvider(), + handler: async (wex, req) => { await removeBackupProvider(wex, req); return {}; - } - case WalletApiOperation.ExportBackupRecovery: { - const resp = await getBackupRecovery(wex); - return resp; - } - case WalletApiOperation.TestingWaitTransactionState: { - const req = payload as TestingWaitTransactionRequest; + }, + }, + [WalletApiOperation.ExportBackupRecovery]: { + codec: codecForEmptyObject(), + handler: getBackupRecovery, + }, + [WalletApiOperation.TestingWaitTransactionState]: { + codec: codecForAny(), + handler: async (wex, req) => { await waitTransactionState(wex, req.transactionId, req.txState); return {}; - } - case WalletApiOperation.GetCurrencySpecification: { - const req = codecForGetCurrencyInfoRequest().decode(payload); - return handleGetCurrencySpecification(wex, req); - } - case WalletApiOperation.ImportBackupRecovery: { - const req = codecForAny().decode(payload); + }, + }, + [WalletApiOperation.GetCurrencySpecification]: { + codec: codecForGetCurrencyInfoRequest(), + handler: handleGetCurrencySpecification, + }, + [WalletApiOperation.ImportBackupRecovery]: { + codec: codecForAny(), + handler: async (wex, req) => { await loadBackupRecovery(wex, req); return {}; - } - case WalletApiOperation.HintNetworkAvailability: { - const req = codecForHintNetworkAvailabilityRequest().decode(payload); - return await handleHintNetworkAvailability(wex, req); - } - case WalletApiOperation.ConvertDepositAmount: { - const req = codecForConvertAmountRequest.decode(payload); - return await convertDepositAmount(wex, req); - } - case WalletApiOperation.GetMaxDepositAmount: { - const req = codecForGetAmountRequest.decode(payload); - return await getMaxDepositAmount(wex, req); - } - case WalletApiOperation.ConvertPeerPushAmount: { - const req = codecForConvertAmountRequest.decode(payload); - return await convertPeerPushAmount(wex, req); - } - case WalletApiOperation.GetMaxPeerPushAmount: { - const req = codecForGetAmountRequest.decode(payload); - return await getMaxPeerPushAmount(wex, req); - } - case WalletApiOperation.ConvertWithdrawalAmount: { - const req = codecForConvertAmountRequest.decode(payload); - return await convertWithdrawalAmount(wex, req); - } - case WalletApiOperation.GetBackupInfo: { - const resp = await getBackupInfo(wex); - return resp; - } - case WalletApiOperation.PrepareDeposit: { - const req = codecForPrepareDepositRequest().decode(payload); - return await checkDepositGroup(wex, req); - } - case WalletApiOperation.GenerateDepositGroupTxId: + }, + }, + [WalletApiOperation.HintNetworkAvailability]: { + codec: codecForHintNetworkAvailabilityRequest(), + handler: handleHintNetworkAvailability, + }, + [WalletApiOperation.ConvertDepositAmount]: { + codec: codecForConvertAmountRequest, + handler: convertDepositAmount, + }, + [WalletApiOperation.GetMaxDepositAmount]: { + codec: codecForGetAmountRequest, + handler: getMaxDepositAmount, + }, + [WalletApiOperation.ConvertPeerPushAmount]: { + codec: codecForConvertAmountRequest, + handler: convertPeerPushAmount, + }, + [WalletApiOperation.GetMaxPeerPushAmount]: { + codec: codecForGetAmountRequest, + handler: getMaxPeerPushAmount, + }, + [WalletApiOperation.ConvertWithdrawalAmount]: { + codec: codecForConvertAmountRequest, + handler: convertWithdrawalAmount, + }, + [WalletApiOperation.GetBackupInfo]: { + codec: codecForEmptyObject(), + handler: getBackupInfo, + }, + [WalletApiOperation.PrepareDeposit]: { + codec: codecForPrepareDepositRequest(), + handler: checkDepositGroup, + }, + [WalletApiOperation.GenerateDepositGroupTxId]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { return { - transactionId: generateDepositGroupTxId(), + transactionId: generateDepositGroupTxId() as TransactionIdStr, }; - case WalletApiOperation.CreateDepositGroup: { - const req = codecForCreateDepositGroupRequest().decode(payload); - return await createDepositGroup(wex, req); - } - case WalletApiOperation.DeleteTransaction: { - const req = codecForDeleteTransactionRequest().decode(payload); + }, + }, + [WalletApiOperation.CreateDepositGroup]: { + codec: codecForCreateDepositGroupRequest(), + handler: createDepositGroup, + }, + [WalletApiOperation.DeleteTransaction]: { + codec: codecForDeleteTransactionRequest(), + handler: async (wex, req) => { await deleteTransaction(wex, req.transactionId); return {}; - } - case WalletApiOperation.RetryTransaction: { - const req = codecForRetryTransactionRequest().decode(payload); + }, + }, + [WalletApiOperation.RetryTransaction]: { + codec: codecForRetryTransactionRequest(), + handler: async (wex, req) => { await retryTransaction(wex, req.transactionId); return {}; - } - case WalletApiOperation.SetWalletDeviceId: { - const req = codecForSetWalletDeviceIdRequest().decode(payload); + }, + }, + [WalletApiOperation.SetWalletDeviceId]: { + codec: codecForSetWalletDeviceIdRequest(), + handler: async (wex, req) => { await setWalletDeviceId(wex, req.walletDeviceId); return {}; - } - case WalletApiOperation.TestCrypto: { + }, + }, + [WalletApiOperation.TestCrypto]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { return await wex.cryptoApi.hashString({ str: "hello world" }); - } - case WalletApiOperation.ClearDb: { + }, + }, + [WalletApiOperation.ClearDb]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { await clearDatabase(wex.db.idbHandle()); wex.ws.clearAllCaches(); return {}; - } - case WalletApiOperation.Recycle: { + }, + }, + [WalletApiOperation.Recycle]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { throw Error("not implemented"); - return {}; - } - case WalletApiOperation.ExportDb: { + }, + }, + [WalletApiOperation.ExportDb]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { const dbDump = await exportDb(wex.ws.idb); return dbDump; - } - case WalletApiOperation.GetDepositWireTypesForCurrency: { - const req = - codecForGetDepositWireTypesForCurrencyRequest().decode(payload); - return handleGetDepositWireTypesForCurrency(wex, req); - } - case WalletApiOperation.ListGlobalCurrencyExchanges: { - const req = codecForEmptyObject().decode(payload); - return await handleListGlobalCurrencyExchanges(wex, req); - } - case WalletApiOperation.ListGlobalCurrencyAuditors: { - const req = codecForEmptyObject().decode(payload); - return await handleListGlobalCurrencyAuditors(wex, req); - } - case WalletApiOperation.AddGlobalCurrencyExchange: { - const req = codecForAddGlobalCurrencyExchangeRequest().decode(payload); - return handleAddGlobalCurrencyExchange(wex, req); - } - case WalletApiOperation.RemoveGlobalCurrencyExchange: { - const req = codecForRemoveGlobalCurrencyExchangeRequest().decode(payload); - return handleRemoveGlobalCurrencyExchange(wex, req); - } - case WalletApiOperation.AddGlobalCurrencyAuditor: { - const req = codecForAddGlobalCurrencyAuditorRequest().decode(payload); - return handleAddGlobalCurrencyAuditor(wex, req); - } - case WalletApiOperation.TestingWaitTasksDone: { + }, + }, + [WalletApiOperation.GetDepositWireTypesForCurrency]: { + codec: codecForGetDepositWireTypesForCurrencyRequest(), + handler: handleGetDepositWireTypesForCurrency, + }, + [WalletApiOperation.ListGlobalCurrencyExchanges]: { + codec: codecForEmptyObject(), + handler: handleListGlobalCurrencyExchanges, + }, + [WalletApiOperation.ListGlobalCurrencyAuditors]: { + codec: codecForEmptyObject(), + handler: handleListGlobalCurrencyAuditors, + }, + [WalletApiOperation.AddGlobalCurrencyExchange]: { + codec: codecForAddGlobalCurrencyExchangeRequest(), + handler: handleAddGlobalCurrencyExchange, + }, + [WalletApiOperation.RemoveGlobalCurrencyExchange]: { + codec: codecForRemoveGlobalCurrencyExchangeRequest(), + handler: handleRemoveGlobalCurrencyExchange, + }, + [WalletApiOperation.AddGlobalCurrencyAuditor]: { + codec: codecForAddGlobalCurrencyAuditorRequest(), + handler: handleAddGlobalCurrencyAuditor, + }, + [WalletApiOperation.TestingWaitTasksDone]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { await waitTasksDone(wex); return {}; - } - case WalletApiOperation.TestingResetAllRetries: + }, + }, + [WalletApiOperation.TestingResetAllRetries]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { await retryAll(wex); return {}; - case WalletApiOperation.RemoveGlobalCurrencyAuditor: { - const req = codecForRemoveGlobalCurrencyAuditorRequest().decode(payload); - return await handleRemoveGlobalCurrencyAuditor(wex, req); - } - case WalletApiOperation.ImportDb: { - const req = codecForImportDbRequest().decode(payload); + }, + }, + [WalletApiOperation.RemoveGlobalCurrencyAuditor]: { + codec: codecForRemoveGlobalCurrencyAuditorRequest(), + handler: handleRemoveGlobalCurrencyAuditor, + }, + [WalletApiOperation.ImportDb]: { + codec: codecForImportDbRequest(), + handler: async (wex, req) => { await importDb(wex.db.idbHandle(), req.dump); - return []; - } - case WalletApiOperation.CheckPeerPushDebit: { - const req = codecForCheckPeerPushDebitRequest().decode(payload); - return await checkPeerPushDebit(wex, req); - } - case WalletApiOperation.InitiatePeerPushDebit: { - const req = codecForInitiatePeerPushDebitRequest().decode(payload); - return await initiatePeerPushDebit(wex, req); - } - case WalletApiOperation.PreparePeerPushCredit: { - const req = codecForPreparePeerPushCreditRequest().decode(payload); - return await preparePeerPushCredit(wex, req); - } - case WalletApiOperation.ConfirmPeerPushCredit: { - const req = codecForConfirmPeerPushPaymentRequest().decode(payload); - return await confirmPeerPushCredit(wex, req); - } - case WalletApiOperation.CheckPeerPullCredit: { - const req = codecForPreparePeerPullPaymentRequest().decode(payload); - return await checkPeerPullPaymentInitiation(wex, req); - } - case WalletApiOperation.InitiatePeerPullCredit: { - const req = codecForInitiatePeerPullPaymentRequest().decode(payload); - return await initiatePeerPullPayment(wex, req); - } - case WalletApiOperation.PreparePeerPullDebit: { - const req = codecForCheckPeerPullPaymentRequest().decode(payload); - return await preparePeerPullDebit(wex, req); - } - case WalletApiOperation.ConfirmPeerPullDebit: { - const req = codecForAcceptPeerPullPaymentRequest().decode(payload); - return await confirmPeerPullDebit(wex, req); - } - case WalletApiOperation.ApplyDevExperiment: { - const req = codecForApplyDevExperiment().decode(payload); + return {}; + }, + }, + [WalletApiOperation.CheckPeerPushDebit]: { + codec: codecForCheckPeerPushDebitRequest(), + handler: checkPeerPushDebit, + }, + [WalletApiOperation.InitiatePeerPushDebit]: { + codec: codecForInitiatePeerPushDebitRequest(), + handler: initiatePeerPushDebit, + }, + [WalletApiOperation.PreparePeerPushCredit]: { + codec: codecForPreparePeerPushCreditRequest(), + handler: preparePeerPushCredit, + }, + [WalletApiOperation.ConfirmPeerPushCredit]: { + codec: codecForConfirmPeerPushPaymentRequest(), + handler: confirmPeerPushCredit, + }, + [WalletApiOperation.CheckPeerPullCredit]: { + codec: codecForPreparePeerPullPaymentRequest(), + handler: checkPeerPullPaymentInitiation, + }, + [WalletApiOperation.InitiatePeerPullCredit]: { + codec: codecForInitiatePeerPullPaymentRequest(), + handler: initiatePeerPullPayment, + }, + [WalletApiOperation.PreparePeerPullDebit]: { + codec: codecForCheckPeerPullPaymentRequest(), + handler: preparePeerPullDebit, + }, + [WalletApiOperation.ConfirmPeerPullDebit]: { + codec: codecForAcceptPeerPullPaymentRequest(), + handler: confirmPeerPullDebit, + }, + [WalletApiOperation.ApplyDevExperiment]: { + codec: codecForApplyDevExperiment(), + handler: async (wex, req) => { await applyDevExperiment(wex, req.devExperimentUri); return {}; - } - case WalletApiOperation.Shutdown: { - const req = codecForEmptyObject().decode(payload); - return await handleShutdown(wex, req); - } - case WalletApiOperation.GetVersion: { - return handleGetVersion(wex); - } - case WalletApiOperation.TestingWaitTransactionsFinal: - return await waitUntilAllTransactionsFinal(wex); - case WalletApiOperation.TestingWaitRefreshesFinal: - return await waitUntilRefreshesDone(wex); - case WalletApiOperation.TestingSetTimetravel: { - const req = codecForTestingSetTimetravelRequest().decode(payload); - return await handleTestingSetTimetravel(wex, req); - } - case WalletApiOperation.DeleteExchange: { - const req = codecForDeleteExchangeRequest().decode(payload); - return await handleDeleteExchange(wex, req); - } - case WalletApiOperation.GetExchangeResources: { - const req = codecForGetExchangeResourcesRequest().decode(payload); + }, + }, + [WalletApiOperation.Shutdown]: { + codec: codecForEmptyObject(), + handler: handleShutdown, + }, + [WalletApiOperation.GetVersion]: { + codec: codecForEmptyObject(), + handler: handleGetVersion, + }, + [WalletApiOperation.TestingWaitTransactionsFinal]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { + await waitUntilAllTransactionsFinal(wex); + return {}; + }, + }, + [WalletApiOperation.TestingWaitRefreshesFinal]: { + codec: codecForEmptyObject(), + handler: async (wex, req) => { + await waitUntilRefreshesDone(wex); + return {}; + }, + }, + [WalletApiOperation.TestingSetTimetravel]: { + codec: codecForTestingSetTimetravelRequest(), + handler: async (wex, req) => { + await handleTestingSetTimetravel(wex, req); + return {}; + }, + }, + [WalletApiOperation.DeleteExchange]: { + codec: codecForDeleteExchangeRequest(), + handler: handleDeleteExchange, + }, + [WalletApiOperation.GetExchangeResources]: { + codec: codecForGetExchangeResourcesRequest(), + handler: async (wex, req) => { return await getExchangeResources(wex, req.exchangeBaseUrl); - } - case WalletApiOperation.CanonicalizeBaseUrl: { - const req = codecForCanonicalizeBaseUrlRequest().decode(payload); - return handleCanonicalizeBaseUrl(wex, req); - } - } - throw TalerError.fromDetail( - TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN, - { - operation, }, - "unknown operation", - ); + }, + [WalletApiOperation.CanonicalizeBaseUrl]: { + codec: codecForCanonicalizeBaseUrlRequest(), + handler: handleCanonicalizeBaseUrl, + }, + [WalletApiOperation.ForceRefresh]: { + codec: codecForForceRefreshRequest(), + handler: async (wex, req) => { + await forceRefresh(wex, req); + return {}; + }, + }, + [WalletApiOperation.GetPlanForOperation]: { + codec: codecForAny(), + handler: async (wex, req) => { + throw Error("not implemented"); + }, + }, + [WalletApiOperation.ExportBackup]: { + codec: codecForAny(), + handler: async (wex, req) => { + throw Error("not implemented"); + }, + }, + [WalletApiOperation.ListAssociatedRefreshes]: { + codec: codecForAny(), + handler: async (wex, req) => { + throw Error("not implemented"); + }, + }, +}; + +/** + * Implementation of the "wallet-core" API. + */ +async function dispatchRequestInternal( + wex: WalletExecutionContext, + operation: WalletApiOperation, + payload: unknown, +): Promise<WalletCoreResponseType<typeof operation>> { + if (!wex.ws.initCalled && operation !== WalletApiOperation.InitWallet) { + throw Error( + `wallet must be initialized before running operation ${operation}`, + ); + } + + const h: HandlerWithValidator<any> = handlers[operation]; + + if (!h) { + throw TalerError.fromDetail( + TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN, + { + operation, + }, + "unknown operation", + ); + } + + const req = h.codec.decode(payload); + return await h.handler(wex, req); } export async function handleGetCurrencySpecification( @@ -2014,7 +2024,9 @@ export async function handleGetCurrencySpecification( return defaultResp; } -function handleGetVersion(wex: WalletExecutionContext): WalletCoreVersion { +async function handleGetVersion( + wex: WalletExecutionContext, +): Promise<WalletCoreVersion> { const result: WalletCoreVersion = { implementationSemver: walletCoreBuildInfo.implementationSemver, implementationGitHash: walletCoreBuildInfo.implementationGitHash, @@ -2034,12 +2046,14 @@ function handleGetVersion(wex: WalletExecutionContext): WalletCoreVersion { export function getObservedWalletExecutionContext( ws: InternalWalletState, cancellationToken: CancellationToken, + cts: CancellationToken.Source | undefined, oc: ObservabilityContext, ): WalletExecutionContext { const db = ws.createDbAccessHandle(cancellationToken); const wex: WalletExecutionContext = { ws, cancellationToken, + cts, cryptoApi: observeTalerCrypto(ws.cryptoApi, oc), db: new ObservableDbAccess(db, oc), http: new ObservableHttpClientLibrary(ws.http, oc), @@ -2052,12 +2066,14 @@ export function getObservedWalletExecutionContext( export function getNormalWalletExecutionContext( ws: InternalWalletState, cancellationToken: CancellationToken, + cts: CancellationToken.Source | undefined, oc: ObservabilityContext, ): WalletExecutionContext { const db = ws.createDbAccessHandle(cancellationToken); const wex: WalletExecutionContext = { ws, cancellationToken, + cts, cryptoApi: ws.cryptoApi, db, get http() { @@ -2106,12 +2122,12 @@ async function handleCoreApiRequest( }, }; - wex = getObservedWalletExecutionContext(ws, cts.token, oc); + wex = getObservedWalletExecutionContext(ws, cts.token, cts, oc); } else { oc = { observe(evt) {}, }; - wex = getNormalWalletExecutionContext(ws, cts.token, oc); + wex = getNormalWalletExecutionContext(ws, cts.token, cts, oc); } try { @@ -2122,7 +2138,6 @@ async function handleCoreApiRequest( }); const result = await dispatchRequestInternal( wex, - cts, operation as any, payload, ); diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts index 93e4784ee..6c489eda2 100644 --- a/packages/taler-wallet-core/src/withdraw.ts +++ b/packages/taler-wallet-core/src/withdraw.ts @@ -3297,8 +3297,6 @@ export async function confirmWithdrawal( * * Thus after this call returns, the withdrawal operation can be confirmed * with the bank. - * - * @deprecated in favor of prepare/accept */ export async function acceptBankIntegratedWithdrawal( wex: WalletExecutionContext, @@ -3724,13 +3722,13 @@ async function internalWaitWithdrawalFinal( 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 cts = wex.cts; + if (clientCancelKey && cts) { const prevCts = wex.ws.clientCancellationMap.get(clientCancelKey); if (prevCts) { wex.oc.observe({ @@ -3757,7 +3755,7 @@ export async function getWithdrawalDetailsForAmount( type: ObservabilityEventType.Message, contents: `Deleting clientCancelKey ${clientCancelKey} to ${cts}`, }); - if (clientCancelKey && !cts.token.isCancelled) { + if (clientCancelKey && wex.cts && !wex.cts.token.isCancelled) { wex.ws.clientCancellationMap.delete(clientCancelKey); } } |