diff options
author | Florian Dold <florian@dold.me> | 2021-06-22 12:18:12 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-06-22 12:18:12 +0200 |
commit | 7383b89cabbfdb8f2fbd6bb9e7b64d09385f7bea (patch) | |
tree | 7700b10f5dad217c0d16b5ac8182cd3af0127abb | |
parent | c4f46cb9d2f755d15e84b639bc6f7bb2546874ce (diff) |
get rid of cyclic imports
-rw-r--r-- | packages/taler-wallet-core/src/common.ts | 60 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/operations/exchanges.ts | 9 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/operations/testing.ts | 11 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 18 |
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. |