aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/wallet.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-06-29 14:16:34 +0200
committerFlorian Dold <florian@dold.me>2024-06-29 14:16:46 +0200
commit98d7a238a615e7dc801bbfdf85188197b91f6083 (patch)
tree6600629dc2b8a70202dd4819d716a5b666cc4020 /packages/taler-wallet-core/src/wallet.ts
parent698be4c436240e97f66a66c3af23192033c818b3 (diff)
downloadwallet-core-98d7a238a615e7dc801bbfdf85188197b91f6083.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.ts632
1 files changed, 387 insertions, 245 deletions
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index c2ec17f48..536f559d4 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -24,29 +24,48 @@
*/
import { IDBDatabase, IDBFactory } from "@gnu-taler/idb-bridge";
import {
+ AbortTransactionRequest,
AbsoluteTime,
+ AcceptManualWithdrawalRequest,
+ AcceptManualWithdrawalResult,
ActiveTask,
AddExchangeRequest,
+ AddKnownBankAccountsRequest,
AmountJson,
AmountString,
Amounts,
CancellationToken,
CoinDumpJson,
CoinStatus,
+ ConfirmPayRequest,
+ ConfirmPayResult,
CoreApiResponse,
CreateStoredBackupResponse,
DeleteStoredBackupRequest,
DenominationInfo,
Duration,
+ EmptyObject,
ExchangesShortListResponse,
+ FailTransactionRequest,
+ ForgetKnownBankAccountsRequest,
+ GetActiveTasksResponse,
+ GetContractTermsDetailsRequest,
GetCurrencySpecificationRequest,
GetCurrencySpecificationResponse,
+ GetDepositWireTypesForCurrencyRequest,
+ GetDepositWireTypesForCurrencyResponse,
+ GetExchangeTosRequest,
+ GetExchangeTosResult,
+ GetQrCodesForPaytoRequest,
+ GetQrCodesForPaytoResponse,
+ HintNetworkAvailabilityRequest,
InitRequest,
InitResponse,
IntegrationTestArgs,
IntegrationTestV2Args,
KnownBankAccounts,
KnownBankAccountsInfo,
+ ListExchangesForScopedCurrencyRequest,
ListGlobalCurrencyAuditorsResponse,
ListGlobalCurrencyExchangesResponse,
Logger,
@@ -61,22 +80,28 @@ import {
RecoverStoredBackupRequest,
SharePaymentRequest,
SharePaymentResult,
+ StartRefundQueryRequest,
StoredBackupList,
+ SuspendTransactionRequest,
TalerBankIntegrationHttpClient,
TalerError,
TalerErrorCode,
TalerProtocolTimestamp,
TalerUriAction,
+ TestingGetDenomStatsRequest,
TestingGetDenomStatsResponse,
+ TestingGetReserveHistoryRequest,
TestingListTasksForTransactionRequest,
TestingListTasksForTransactionsResponse,
TestingWaitTransactionRequest,
TimerAPI,
TimerGroup,
TransactionType,
+ TransactionsResponse,
UpdateExchangeEntryRequest,
ValidateIbanRequest,
ValidateIbanResponse,
+ WalletContractData,
WalletCoreVersion,
WalletNotification,
WalletRunConfig,
@@ -106,6 +131,7 @@ import {
codecForDeleteExchangeRequest,
codecForDeleteStoredBackupRequest,
codecForDeleteTransactionRequest,
+ codecForEmptyObject,
codecForFailTransactionRequest,
codecForForceRefreshRequest,
codecForForgetKnownBankAccounts,
@@ -167,7 +193,6 @@ import {
parseTalerUri,
performanceNow,
safeStringifyException,
- sampleWalletCoreTransactions,
setDangerousTimetravel,
validateIban,
} from "@gnu-taler/taler-util";
@@ -181,6 +206,7 @@ import {
markAttentionRequestAsRead,
} from "./attention.js";
import {
+ RunBackupCycleRequest,
addBackupProvider,
codecForAddBackupProviderRequest,
codecForRemoveBackupProvider,
@@ -318,7 +344,6 @@ import {
WALLET_MERCHANT_PROTOCOL_VERSION,
} from "./versions.js";
import {
- EmptyObject,
WalletApiOperation,
WalletCoreApiClient,
WalletCoreResponseType,
@@ -693,18 +718,6 @@ async function handlePrepareWithdrawExchange(
};
}
-/**
- * Response returned from the pending operations API.
- *
- * @deprecated this is a placeholder for the response type of a deprecated wallet-core request.
- */
-export interface PendingOperationsResponse {
- /**
- * List of pending operations.
- */
- pendingOperations: any[];
-}
-
async function handleRetryPendingNow(
wex: WalletExecutionContext,
): Promise<EmptyObject> {
@@ -857,6 +870,343 @@ async function handleUpdateExchangeEntry(
return {};
}
+async function handleTestingGetDenomStats(
+ wex: WalletExecutionContext,
+ req: TestingGetDenomStatsRequest,
+): Promise<TestingGetDenomStatsResponse> {
+ const denomStats: TestingGetDenomStatsResponse = {
+ numKnown: 0,
+ numLost: 0,
+ numOffered: 0,
+ };
+ await wex.db.runReadOnlyTx({ storeNames: ["denominations"] }, async (tx) => {
+ const denoms = await tx.denominations.indexes.byExchangeBaseUrl.getAll(
+ req.exchangeBaseUrl,
+ );
+ for (const d of denoms) {
+ denomStats.numKnown++;
+ if (d.isOffered) {
+ denomStats.numOffered++;
+ }
+ if (d.isLost) {
+ denomStats.numLost++;
+ }
+ }
+ });
+ return denomStats;
+}
+
+async function handleListExchangesForScopedCurrency(
+ wex: WalletExecutionContext,
+ req: ListExchangesForScopedCurrencyRequest,
+): Promise<ExchangesShortListResponse> {
+ const exchangesResp = await listExchanges(wex);
+ const result: ExchangesShortListResponse = {
+ exchanges: [],
+ };
+ // Right now we only filter on the currency, as wallet-core doesn't
+ // fully support scoped currencies yet.
+ for (const exch of exchangesResp.exchanges) {
+ if (exch.currency === req.scope.currency) {
+ result.exchanges.push({
+ exchangeBaseUrl: exch.exchangeBaseUrl,
+ });
+ }
+ }
+ return result;
+}
+
+async function handleAddKnownBankAccount(
+ wex: WalletExecutionContext,
+ req: AddKnownBankAccountsRequest,
+): Promise<EmptyObject> {
+ await addKnownBankAccounts(wex, req.payto, req.alias, req.currency);
+ return {};
+}
+
+async function handleForgetKnownBankAccounts(
+ wex: WalletExecutionContext,
+ req: ForgetKnownBankAccountsRequest,
+): Promise<EmptyObject> {
+ await forgetKnownBankAccounts(wex, req.payto);
+ return {};
+}
+
+// FIXME: Doesn't have proper type!
+async function handleTestingGetReserveHistory(
+ wex: WalletExecutionContext,
+ req: TestingGetReserveHistoryRequest,
+): Promise<any> {
+ const reserve = await wex.db.runReadOnlyTx(
+ { storeNames: ["reserves"] },
+ async (tx) => {
+ return tx.reserves.indexes.byReservePub.get(req.reservePub);
+ },
+ );
+ if (!reserve) {
+ throw Error("no reserve pub found");
+ }
+ const sigResp = await wex.cryptoApi.signReserveHistoryReq({
+ reservePriv: reserve.reservePriv,
+ startOffset: 0,
+ });
+ const exchangeBaseUrl = req.exchangeBaseUrl;
+ const url = new URL(`reserves/${req.reservePub}/history`, exchangeBaseUrl);
+ const resp = await wex.http.fetch(url.href, {
+ headers: { ["Taler-Reserve-History-Signature"]: sigResp.sig },
+ });
+ const historyJson = await readSuccessResponseJsonOrThrow(resp, codecForAny());
+ return historyJson;
+}
+
+async function handleAcceptManualWithdrawal(
+ wex: WalletExecutionContext,
+ req: AcceptManualWithdrawalRequest,
+): Promise<AcceptManualWithdrawalResult> {
+ const res = await createManualWithdrawal(wex, {
+ amount: Amounts.parseOrThrow(req.amount),
+ exchangeBaseUrl: req.exchangeBaseUrl,
+ restrictAge: req.restrictAge,
+ forceReservePriv: req.forceReservePriv,
+ });
+ return res;
+}
+
+async function handleGetExchangeTos(
+ wex: WalletExecutionContext,
+ req: GetExchangeTosRequest,
+): Promise<GetExchangeTosResult> {
+ return getExchangeTos(
+ wex,
+ req.exchangeBaseUrl,
+ req.acceptedFormat,
+ req.acceptLanguage,
+ );
+}
+
+async function handleGetContractTermsDetails(
+ wex: WalletExecutionContext,
+ req: GetContractTermsDetailsRequest,
+): Promise<WalletContractData> {
+ if (req.proposalId) {
+ // FIXME: deprecated path
+ return getContractTermsDetails(wex, req.proposalId);
+ }
+ if (req.transactionId) {
+ const parsedTx = parseTransactionIdentifier(req.transactionId);
+ if (parsedTx?.tag === TransactionType.Payment) {
+ return getContractTermsDetails(wex, parsedTx.proposalId);
+ }
+ throw Error("transactionId is not a payment transaction");
+ }
+ throw Error("transactionId missing");
+}
+
+async function handleGetQrCodesForPayto(
+ wex: WalletExecutionContext,
+ req: GetQrCodesForPaytoRequest,
+): Promise<GetQrCodesForPaytoResponse> {
+ return {
+ codes: getQrCodesForPayto(req.paytoUri),
+ };
+}
+
+async function handleConfirmPay(
+ wex: WalletExecutionContext,
+ req: ConfirmPayRequest,
+): Promise<ConfirmPayResult> {
+ let transactionId;
+ if (req.proposalId) {
+ // legacy client support
+ transactionId = constructTransactionIdentifier({
+ tag: TransactionType.Payment,
+ proposalId: req.proposalId,
+ });
+ } else if (req.transactionId) {
+ transactionId = req.transactionId;
+ } else {
+ throw Error("transactionId or (deprecated) proposalId required");
+ }
+ return await confirmPay(wex, transactionId, req.sessionId);
+}
+
+async function handleAbortTransaction(
+ wex: WalletExecutionContext,
+ req: AbortTransactionRequest,
+): Promise<EmptyObject> {
+ await abortTransaction(wex, req.transactionId);
+ return {};
+}
+
+async function handleSuspendTransaction(
+ wex: WalletExecutionContext,
+ req: SuspendTransactionRequest,
+): Promise<EmptyObject> {
+ await suspendTransaction(wex, req.transactionId);
+ return {};
+}
+
+async function handleGetActiveTasks(
+ wex: WalletExecutionContext,
+ req: EmptyObject,
+): Promise<GetActiveTasksResponse> {
+ const allTasksId = (await getActiveTaskIds(wex.ws)).taskIds;
+
+ const tasksInfo = await Promise.all(
+ allTasksId.map(async (id) => {
+ return await wex.db.runReadOnlyTx(
+ { storeNames: ["operationRetries"] },
+ async (tx) => {
+ return tx.operationRetries.get(id);
+ },
+ );
+ }),
+ );
+
+ const tasks = allTasksId.map((taskId, i): ActiveTask => {
+ const transaction = convertTaskToTransactionId(taskId);
+ const d = tasksInfo[i];
+
+ const firstTry = !d
+ ? undefined
+ : timestampAbsoluteFromDb(d.retryInfo.firstTry);
+ const nextTry = !d
+ ? undefined
+ : timestampAbsoluteFromDb(d.retryInfo.nextRetry);
+ const counter = d?.retryInfo.retryCounter;
+ const lastError = d?.lastError;
+
+ return {
+ taskId: taskId,
+ retryCounter: counter,
+ firstTry,
+ nextTry,
+ lastError,
+ transaction,
+ };
+ });
+ return { tasks };
+}
+
+async function handleFailTransaction(
+ wex: WalletExecutionContext,
+ req: FailTransactionRequest,
+): Promise<EmptyObject> {
+ await failTransaction(wex, req.transactionId);
+ return {};
+}
+
+async function handleTestingGetSampleTransactions(
+ wex: WalletExecutionContext,
+ req: EmptyObject,
+): Promise<TransactionsResponse> {
+ // FIXME!
+ return { transactions: [] };
+ // These are out of date!
+ //return { transactions: sampleWalletCoreTransactions };
+}
+
+async function handleStartRefundQuery(
+ wex: WalletExecutionContext,
+ req: StartRefundQueryRequest,
+): Promise<EmptyObject> {
+ const txIdParsed = parseTransactionIdentifier(req.transactionId);
+ if (!txIdParsed) {
+ throw Error("invalid transaction ID");
+ }
+ if (txIdParsed.tag !== TransactionType.Payment) {
+ throw Error("expected payment transaction ID");
+ }
+ await startQueryRefund(wex, txIdParsed.proposalId);
+ return {};
+}
+
+async function handleAddBackupProvider(
+ wex: WalletExecutionContext,
+ req: RunBackupCycleRequest,
+): Promise<EmptyObject> {
+ await runBackupCycle(wex, req);
+ return {};
+}
+
+async function handleHintNetworkAvailability(
+ wex: WalletExecutionContext,
+ req: HintNetworkAvailabilityRequest,
+): Promise<EmptyObject> {
+ wex.ws.networkAvailable = req.isNetworkAvailable;
+ // When network becomes available, restart tasks as they're blocked
+ // waiting for the network.
+ // When network goes down, restart tasks so they notice the network
+ // is down and wait.
+ await restartAllRunningTasks(wex);
+ return {};
+}
+
+async function handleGetDepositWireTypesForCurrency(
+ wex: WalletExecutionContext,
+ req: GetDepositWireTypesForCurrencyRequest,
+): Promise<GetDepositWireTypesForCurrencyResponse> {
+ const wtSet: Set<string> = new Set();
+ await wex.db.runReadOnlyTx(
+ { storeNames: ["exchanges", "exchangeDetails"] },
+ async (tx) => {
+ const exchanges = await tx.exchanges.getAll();
+ for (const exchange of exchanges) {
+ const det = await getExchangeWireDetailsInTx(tx, exchange.baseUrl);
+ if (!det) {
+ continue;
+ }
+ if (det.currency !== req.currency) {
+ continue;
+ }
+ for (const acc of det.wireInfo.accounts) {
+ let usable = true;
+ for (const dr of acc.debit_restrictions) {
+ if (dr.type === "deny") {
+ usable = false;
+ break;
+ }
+ }
+ if (!usable) {
+ break;
+ }
+ const parsedPayto = parsePaytoUri(acc.payto_uri);
+ if (!parsedPayto) {
+ continue;
+ }
+ wtSet.add(parsedPayto.targetType);
+ }
+ }
+ },
+ );
+ return {
+ wireTypes: [...wtSet],
+ };
+}
+
+async function handleListGlobalCurrencyExchanges(
+ wex: WalletExecutionContext,
+ req: EmptyObject,
+): Promise<ListGlobalCurrencyExchangesResponse> {
+ const resp: ListGlobalCurrencyExchangesResponse = {
+ exchanges: [],
+ };
+ await wex.db.runReadOnlyTx(
+ { storeNames: ["globalCurrencyExchanges"] },
+ async (tx) => {
+ const gceList = await tx.globalCurrencyExchanges.iter().toArray();
+ for (const gce of gceList) {
+ resp.exchanges.push({
+ currency: gce.currency,
+ exchangeBaseUrl: gce.exchangeBaseUrl,
+ exchangeMasterPub: gce.exchangeMasterPub,
+ });
+ }
+ },
+ );
+ return resp;
+}
+
/**
* Implementation of the "wallet-core" API.
*/
@@ -944,30 +1294,7 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.TestingGetDenomStats: {
const req = codecForTestingGetDenomStatsRequest().decode(payload);
- const denomStats: TestingGetDenomStatsResponse = {
- numKnown: 0,
- numLost: 0,
- numOffered: 0,
- };
- await wex.db.runReadOnlyTx(
- { storeNames: ["denominations"] },
- async (tx) => {
- const denoms =
- await tx.denominations.indexes.byExchangeBaseUrl.getAll(
- req.exchangeBaseUrl,
- );
- for (const d of denoms) {
- denomStats.numKnown++;
- if (d.isOffered) {
- denomStats.numOffered++;
- }
- if (d.isLost) {
- denomStats.numLost++;
- }
- }
- },
- );
- return denomStats;
+ return handleTestingGetDenomStats(wex, req);
}
case WalletApiOperation.ListExchanges: {
return await listExchanges(wex);
@@ -979,20 +1306,7 @@ async function dispatchRequestInternal(
case WalletApiOperation.ListExchangesForScopedCurrency: {
const req =
codecForListExchangesForScopedCurrencyRequest().decode(payload);
- const exchangesResp = await listExchanges(wex);
- const result: ExchangesShortListResponse = {
- exchanges: [],
- };
- // Right now we only filter on the currency, as wallet-core doesn't
- // fully support scoped currencies yet.
- for (const exch of exchangesResp.exchanges) {
- if (exch.currency === req.scope.currency) {
- result.exchanges.push({
- exchangeBaseUrl: exch.exchangeBaseUrl,
- });
- }
- }
- return result;
+ return await handleListExchangesForScopedCurrency(wex, req);
}
case WalletApiOperation.GetExchangeDetailedInfo: {
const req = codecForAddExchangeRequest().decode(payload);
@@ -1004,13 +1318,11 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.AddKnownBankAccounts: {
const req = codecForAddKnownBankAccounts().decode(payload);
- await addKnownBankAccounts(wex, req.payto, req.alias, req.currency);
- return {};
+ return await handleAddKnownBankAccount(wex, req);
}
case WalletApiOperation.ForgetKnownBankAccounts: {
const req = codecForForgetKnownBankAccounts().decode(payload);
- await forgetKnownBankAccounts(wex, req.payto);
- return {};
+ return await handleForgetKnownBankAccounts(wex, req);
}
case WalletApiOperation.GetWithdrawalDetailsForUri: {
const req = codecForGetWithdrawalDetailsForUri().decode(payload);
@@ -1018,48 +1330,16 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.TestingGetReserveHistory: {
const req = codecForTestingGetReserveHistoryRequest().decode(payload);
- const reserve = await wex.db.runReadOnlyTx(
- { storeNames: ["reserves"] },
- async (tx) => {
- return tx.reserves.indexes.byReservePub.get(req.reservePub);
- },
- );
- if (!reserve) {
- throw Error("no reserve pub found");
- }
- const sigResp = await wex.cryptoApi.signReserveHistoryReq({
- reservePriv: reserve.reservePriv,
- startOffset: 0,
- });
- const exchangeBaseUrl = req.exchangeBaseUrl;
- const url = new URL(
- `reserves/${req.reservePub}/history`,
- exchangeBaseUrl,
- );
- const resp = await wex.http.fetch(url.href, {
- headers: { ["Taler-Reserve-History-Signature"]: sigResp.sig },
- });
- const historyJson = await readSuccessResponseJsonOrThrow(
- resp,
- codecForAny(),
- );
- return historyJson;
+ return await handleTestingGetReserveHistory(wex, req);
}
case WalletApiOperation.AcceptManualWithdrawal: {
const req = codecForAcceptManualWithdrawalRequest().decode(payload);
- const res = await createManualWithdrawal(wex, {
- amount: Amounts.parseOrThrow(req.amount),
- exchangeBaseUrl: req.exchangeBaseUrl,
- restrictAge: req.restrictAge,
- forceReservePriv: req.forceReservePriv,
- });
- return res;
+ return await handleAcceptManualWithdrawal(wex, req);
}
case WalletApiOperation.GetWithdrawalDetailsForAmount: {
const req =
codecForGetWithdrawalDetailsForAmountRequest().decode(payload);
- const resp = await getWithdrawalDetailsForAmount(wex, cts, req);
- return resp;
+ return await getWithdrawalDetailsForAmount(wex, cts, req);
}
case WalletApiOperation.GetBalances: {
return await getBalances(wex);
@@ -1080,12 +1360,6 @@ async function dispatchRequestInternal(
const req = codecForUserAttentionsRequest().decode(payload);
return await getUserAttentionsUnreadCount(wex, req);
}
- case WalletApiOperation.GetPendingOperations: {
- // FIXME: Eventually remove the handler after deprecation period.
- return {
- pendingOperations: [],
- } satisfies PendingOperationsResponse;
- }
case WalletApiOperation.SetExchangeTosAccepted: {
const req = codecForAcceptExchangeTosRequest().decode(payload);
await acceptExchangeTermsOfService(wex, req.exchangeBaseUrl);
@@ -1118,27 +1392,11 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.GetExchangeTos: {
const req = codecForGetExchangeTosRequest().decode(payload);
- return getExchangeTos(
- wex,
- req.exchangeBaseUrl,
- req.acceptedFormat,
- req.acceptLanguage,
- );
+ return await handleGetExchangeTos(wex, req);
}
case WalletApiOperation.GetContractTermsDetails: {
const req = codecForGetContractTermsDetails().decode(payload);
- if (req.proposalId) {
- // FIXME: deprecated path
- return getContractTermsDetails(wex, req.proposalId);
- }
- if (req.transactionId) {
- const parsedTx = parseTransactionIdentifier(req.transactionId);
- if (parsedTx?.tag === TransactionType.Payment) {
- return getContractTermsDetails(wex, parsedTx.proposalId);
- }
- throw Error("transactionId is not a payment transaction");
- }
- throw Error("transactionId missing");
+ return handleGetContractTermsDetails(wex, req);
}
case WalletApiOperation.RetryPendingNow: {
return handleRetryPendingNow(wex);
@@ -1165,78 +1423,26 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.GetQrCodesForPayto: {
const req = codecForGetQrCodesForPaytoRequest().decode(payload);
- return {
- codes: getQrCodesForPayto(req.paytoUri),
- };
+ return handleGetQrCodesForPayto(wex, req);
}
case WalletApiOperation.ConfirmPay: {
const req = codecForConfirmPayRequest().decode(payload);
- let transactionId;
- if (req.proposalId) {
- // legacy client support
- transactionId = constructTransactionIdentifier({
- tag: TransactionType.Payment,
- proposalId: req.proposalId,
- });
- } else if (req.transactionId) {
- transactionId = req.transactionId;
- } else {
- throw Error("transactionId or (deprecated) proposalId required");
- }
- return await confirmPay(wex, transactionId, req.sessionId);
+ return handleConfirmPay(wex, req);
}
case WalletApiOperation.AbortTransaction: {
const req = codecForAbortTransaction().decode(payload);
- await abortTransaction(wex, req.transactionId);
- return {};
+ return handleAbortTransaction(wex, req);
}
case WalletApiOperation.SuspendTransaction: {
const req = codecForSuspendTransaction().decode(payload);
- await suspendTransaction(wex, req.transactionId);
- return {};
+ return handleSuspendTransaction(wex, req);
}
case WalletApiOperation.GetActiveTasks: {
- const allTasksId = (await getActiveTaskIds(wex.ws)).taskIds;
-
- const tasksInfo = await Promise.all(
- allTasksId.map(async (id) => {
- return await wex.db.runReadOnlyTx(
- { storeNames: ["operationRetries"] },
- async (tx) => {
- return tx.operationRetries.get(id);
- },
- );
- }),
- );
-
- const tasks = allTasksId.map((taskId, i): ActiveTask => {
- const transaction = convertTaskToTransactionId(taskId);
- const d = tasksInfo[i];
-
- const firstTry = !d
- ? undefined
- : timestampAbsoluteFromDb(d.retryInfo.firstTry);
- const nextTry = !d
- ? undefined
- : timestampAbsoluteFromDb(d.retryInfo.nextRetry);
- const counter = d?.retryInfo.retryCounter;
- const lastError = d?.lastError;
-
- return {
- taskId: taskId,
- retryCounter: counter,
- firstTry,
- nextTry,
- lastError,
- transaction,
- };
- });
- return { tasks };
+ return await handleGetActiveTasks(wex, {});
}
case WalletApiOperation.FailTransaction: {
const req = codecForFailTransactionRequest().decode(payload);
- await failTransaction(wex, req.transactionId);
- return {};
+ return await handleFailTransaction(wex, req);
}
case WalletApiOperation.ResumeTransaction: {
const req = codecForResumeTransaction().decode(payload);
@@ -1252,7 +1458,8 @@ async function dispatchRequestInternal(
return {};
}
case WalletApiOperation.TestingGetSampleTransactions:
- return { transactions: sampleWalletCoreTransactions };
+ const req = codecForEmptyObject().decode(payload);
+ return handleTestingGetSampleTransactions(wex, req);
case WalletApiOperation.ForceRefresh: {
const req = codecForForceRefreshRequest().decode(payload);
return await forceRefresh(wex, req);
@@ -1263,15 +1470,7 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.StartRefundQuery: {
const req = codecForStartRefundQueryRequest().decode(payload);
- const txIdParsed = parseTransactionIdentifier(req.transactionId);
- if (!txIdParsed) {
- throw Error("invalid transaction ID");
- }
- if (txIdParsed.tag !== TransactionType.Payment) {
- throw Error("expected payment transaction ID");
- }
- await startQueryRefund(wex, txIdParsed.proposalId);
- return {};
+ return handleStartRefundQuery(wex, req);
}
case WalletApiOperation.AddBackupProvider: {
const req = codecForAddBackupProviderRequest().decode(payload);
@@ -1279,8 +1478,7 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.RunBackupCycle: {
const req = codecForRunBackupCycle().decode(payload);
- await runBackupCycle(wex, req);
- return {};
+ return handleAddBackupProvider(wex, req);
}
case WalletApiOperation.RemoveBackupProvider: {
const req = codecForRemoveBackupProvider().decode(payload);
@@ -1307,13 +1505,7 @@ async function dispatchRequestInternal(
}
case WalletApiOperation.HintNetworkAvailability: {
const req = codecForHintNetworkAvailabilityRequest().decode(payload);
- wex.ws.networkAvailable = req.isNetworkAvailable;
- // When network becomes available, restart tasks as they're blocked
- // waiting for the network.
- // When network goes down, restart tasks so they notice the network
- // is down and wait.
- await restartAllRunningTasks(wex);
- return {};
+ return await handleHintNetworkAvailability(wex, req);
}
case WalletApiOperation.ConvertDepositAmount: {
const req = codecForConvertAmountRequest.decode(payload);
@@ -1385,61 +1577,11 @@ async function dispatchRequestInternal(
case WalletApiOperation.GetDepositWireTypesForCurrency: {
const req =
codecForGetDepositWireTypesForCurrencyRequest().decode(payload);
- const wtSet: Set<string> = new Set();
- await wex.db.runReadOnlyTx(
- { storeNames: ["exchanges", "exchangeDetails"] },
- async (tx) => {
- const exchanges = await tx.exchanges.getAll();
- for (const exchange of exchanges) {
- const det = await getExchangeWireDetailsInTx(tx, exchange.baseUrl);
- if (!det) {
- continue;
- }
- if (det.currency !== req.currency) {
- continue;
- }
- for (const acc of det.wireInfo.accounts) {
- let usable = true;
- for (const dr of acc.debit_restrictions) {
- if (dr.type === "deny") {
- usable = false;
- break;
- }
- }
- if (!usable) {
- break;
- }
- const parsedPayto = parsePaytoUri(acc.payto_uri);
- if (!parsedPayto) {
- continue;
- }
- wtSet.add(parsedPayto.targetType);
- }
- }
- },
- );
- return {
- wireTypes: [...wtSet],
- };
+ return handleGetDepositWireTypesForCurrency(wex, req);
}
case WalletApiOperation.ListGlobalCurrencyExchanges: {
- const resp: ListGlobalCurrencyExchangesResponse = {
- exchanges: [],
- };
- await wex.db.runReadOnlyTx(
- { storeNames: ["globalCurrencyExchanges"] },
- async (tx) => {
- const gceList = await tx.globalCurrencyExchanges.iter().toArray();
- for (const gce of gceList) {
- resp.exchanges.push({
- currency: gce.currency,
- exchangeBaseUrl: gce.exchangeBaseUrl,
- exchangeMasterPub: gce.exchangeMasterPub,
- });
- }
- },
- );
- return resp;
+ const req = codecForEmptyObject().decode(payload);
+ return await handleListGlobalCurrencyExchanges(wex, req);
}
case WalletApiOperation.ListGlobalCurrencyAuditors: {
const resp: ListGlobalCurrencyAuditorsResponse = {