aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-06-22 12:18:12 +0200
committerFlorian Dold <florian@dold.me>2021-06-22 12:18:12 +0200
commit7383b89cabbfdb8f2fbd6bb9e7b64d09385f7bea (patch)
tree7700b10f5dad217c0d16b5ac8182cd3af0127abb
parentc4f46cb9d2f755d15e84b639bc6f7bb2546874ce (diff)
get rid of cyclic imports
-rw-r--r--packages/taler-wallet-core/src/common.ts60
-rw-r--r--packages/taler-wallet-core/src/operations/exchanges.ts9
-rw-r--r--packages/taler-wallet-core/src/operations/testing.ts11
-rw-r--r--packages/taler-wallet-core/src/wallet.ts18
4 files changed, 68 insertions, 30 deletions
diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts
index a52877b33..128138eb2 100644
--- a/packages/taler-wallet-core/src/common.ts
+++ b/packages/taler-wallet-core/src/common.ts
@@ -15,33 +15,34 @@
*/
/**
+ * Common interface of the internal wallet state. This object is passed
+ * to the various operations (exchange management, withdrawal, refresh, reserve
+ * management, etc.).
+ *
+ * Some operations can be accessed via this state object. This allows mutual
+ * recursion between operations, without having cycling dependencies between
+ * the respective TypeScript files.
+ *
+ * (You can think of this as a "header file" for the wallet implementation.)
+ */
+
+/**
* Imports.
*/
-import {
- WalletNotification,
- BalancesResponse,
- Logger,
-} from "@gnu-taler/taler-util";
-import { CryptoApi, CryptoWorkerFactory } from "./crypto/workers/cryptoApi.js";
+import { WalletNotification, BalancesResponse } from "@gnu-taler/taler-util";
+import { CryptoApi } from "./crypto/workers/cryptoApi.js";
import { ExchangeDetailsRecord, ExchangeRecord, WalletStoresV1 } from "./db.js";
-import {
- getExchangeDetails,
- getExchangeTrust,
- updateExchangeFromUrl,
-} from "./operations/exchanges.js";
import { PendingOperationsResponse } from "./pending-types.js";
import { AsyncOpMemoMap, AsyncOpMemoSingle } from "./util/asyncMemo.js";
import { HttpRequestLibrary } from "./util/http.js";
+import { AsyncCondition } from "./util/promiseUtils.js";
import {
- AsyncCondition,
- OpenedPromise,
- openPromise,
-} from "./util/promiseUtils.js";
-import { DbAccess, GetReadOnlyAccess } from "./util/query.js";
+ DbAccess,
+ GetReadOnlyAccess,
+ GetReadWriteAccess,
+} from "./util/query.js";
import { TimerGroup } from "./util/timer.js";
-const logger = new Logger("state.ts");
-
export const EXCHANGE_COINS_LOCK = "exchange-coins-lock";
export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock";
@@ -77,12 +78,30 @@ export interface ExchangeOperations {
}>;
}
+export interface RecoupOperations {
+ createRecoupGroup(
+ ws: InternalWalletState,
+ tx: GetReadWriteAccess<{
+ recoupGroups: typeof WalletStoresV1.recoupGroups;
+ denominations: typeof WalletStoresV1.denominations;
+ refreshGroups: typeof WalletStoresV1.refreshGroups;
+ coins: typeof WalletStoresV1.coins;
+ }>,
+ coinPubs: string[],
+ ): Promise<string>;
+ processRecoupGroup(
+ ws: InternalWalletState,
+ recoupGroupId: string,
+ forceNow?: boolean,
+ ): Promise<void>;
+}
+
export type NotificationListener = (n: WalletNotification) => void;
/**
* Internal, shard wallet state that is used by the implementation
* of wallet operations.
- *
+ *
* FIXME: This should not be exported anywhere from the taler-wallet-core package,
* as it's an opaque implementation detail.
*/
@@ -106,6 +125,7 @@ export interface InternalWalletState {
initCalled: boolean;
exchangeOps: ExchangeOperations;
+ recoupOps: RecoupOperations;
db: DbAccess<typeof WalletStoresV1>;
http: HttpRequestLibrary;
@@ -124,4 +144,6 @@ export interface InternalWalletState {
* by string tokens.
*/
runSequentialized<T>(tokens: string[], f: () => Promise<T>): Promise<T>;
+
+ runUntilDone(req?: { maxRetries?: number }): Promise<void>;
}
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts
index 85455cf9c..a04769929 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -65,7 +65,6 @@ import {
makeErrorDetails,
OperationFailedError,
} from "../errors.js";
-import { createRecoupGroup, processRecoupGroup } from "./recoup.js";
import { InternalWalletState, TrustInfo } from "../common.js";
import {
WALLET_CACHE_BREAKER_CLIENT_VERSION,
@@ -556,7 +555,11 @@ async function updateExchangeFromUrlImpl(
}
if (newlyRevokedCoinPubs.length != 0) {
logger.trace("recouping coins", newlyRevokedCoinPubs);
- recoupGroupId = await createRecoupGroup(ws, tx, newlyRevokedCoinPubs);
+ recoupGroupId = await ws.recoupOps.createRecoupGroup(
+ ws,
+ tx,
+ newlyRevokedCoinPubs,
+ );
}
return {
exchange: r,
@@ -567,7 +570,7 @@ async function updateExchangeFromUrlImpl(
if (recoupGroupId) {
// Asynchronously start recoup. This doesn't need to finish
// for the exchange update to be considered finished.
- processRecoupGroup(ws, recoupGroupId).catch((e) => {
+ ws.recoupOps.processRecoupGroup(ws, recoupGroupId).catch((e) => {
logger.error("error while recouping coins:", e);
});
}
diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts
index c9786801b..dd7d8c7cb 100644
--- a/packages/taler-wallet-core/src/operations/testing.ts
+++ b/packages/taler-wallet-core/src/operations/testing.ts
@@ -38,7 +38,6 @@ import { createTalerWithdrawReserve } from "./reserves.js";
import { InternalWalletState } from "../common.js";
import { confirmPay, preparePayForUri } from "./pay.js";
import { getBalances } from "./balance.js";
-import { runUntilDone } from "../wallet.js";
import { applyRefund } from "./refund.js";
const logger = new Logger("operations/testing.ts");
@@ -333,7 +332,7 @@ export async function runIntegrationTest(
args.bankBaseUrl,
args.exchangeBaseUrl,
);
- await runUntilDone(ws);
+ await ws.runUntilDone();
logger.info("done withdrawing test balance");
const balance = await getBalances(ws);
@@ -348,7 +347,7 @@ export async function runIntegrationTest(
await makePayment(ws, myMerchant, args.amountToSpend, "hello world");
// Wait until the refresh is done
- await runUntilDone(ws);
+ await ws.runUntilDone();
logger.trace("withdrawing test balance for refund");
const withdrawAmountTwo = Amounts.parseOrThrow(`${currency}:18`);
@@ -364,7 +363,7 @@ export async function runIntegrationTest(
);
// Wait until the withdraw is done
- await runUntilDone(ws);
+ await ws.runUntilDone();
const { orderId: refundOrderId } = await makePayment(
ws,
@@ -388,7 +387,7 @@ export async function runIntegrationTest(
logger.trace("integration test: applied refund");
// Wait until the refund is done
- await runUntilDone(ws);
+ await ws.runUntilDone();
logger.trace("integration test: making payment after refund");
@@ -401,7 +400,7 @@ export async function runIntegrationTest(
logger.trace("integration test: make payment done");
- await runUntilDone(ws);
+ await ws.runUntilDone();
logger.trace("integration test: all done!");
}
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 3a3b4f6fd..6a7ee9de1 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -33,7 +33,6 @@ import {
getDurationRemaining,
isTimestampExpired,
j2s,
- PreparePayResultType,
TalerErrorCode,
Timestamp,
timestampMin,
@@ -72,7 +71,7 @@ import {
processPurchasePay,
} from "./operations/pay.js";
import { getPendingOperations } from "./operations/pending.js";
-import { processRecoupGroup } from "./operations/recoup.js";
+import { createRecoupGroup, processRecoupGroup } from "./operations/recoup.js";
import {
autoRefresh,
createRefreshGroup,
@@ -93,6 +92,7 @@ import {
ExchangeOperations,
InternalWalletState,
NotificationListener,
+ RecoupOperations,
} from "./common.js";
import {
runIntegrationTest,
@@ -673,6 +673,7 @@ async function dispatchRequestInternal(
switch (operation) {
case "initWallet": {
ws.initCalled = true;
+ await fillDefaults(ws);
return {};
}
case "withdrawTestkudos": {
@@ -1046,6 +1047,11 @@ class InternalWalletStateImpl implements InternalWalletState {
updateExchangeFromUrl,
};
+ recoupOps: RecoupOperations = {
+ createRecoupGroup: createRecoupGroup,
+ processRecoupGroup: processRecoupGroup,
+ };
+
/**
* Promises that are waiting for a particular resource.
*/
@@ -1091,6 +1097,14 @@ class InternalWalletStateImpl implements InternalWalletState {
this.cryptoApi.stop();
}
+ async runUntilDone(
+ req: {
+ maxRetries?: number;
+ } = {},
+ ): Promise<void> {
+ runUntilDone(this, req);
+ }
+
/**
* Run an async function after acquiring a list of locks, identified
* by string tokens.