diff options
author | Florian Dold <florian@dold.me> | 2021-06-15 18:52:43 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-06-15 18:52:43 +0200 |
commit | d41ae5eb97a5264b1d61321354eac049ca317c97 (patch) | |
tree | a8e78bee0ff2a92f0b3f1cb9230442186dd17358 /packages/taler-wallet-core/src/operations | |
parent | 4b16d7bd342dbb5376fd2cef08b14ebabbe4ed10 (diff) | |
download | wallet-core-d41ae5eb97a5264b1d61321354eac049ca317c97.tar.xz |
separate wallet state from wallet client
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
6 files changed, 89 insertions, 55 deletions
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index 00a76bd19..2cc056721 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -38,7 +38,10 @@ import { WalletBackupConfState, WALLET_BACKUP_STATE_KEY, } from "../../db.js"; -import { checkDbInvariant, checkLogicInvariant } from "../../util/invariants.js"; +import { + checkDbInvariant, + checkLogicInvariant, +} from "../../util/invariants.js"; import { bytesToString, decodeCrock, @@ -83,8 +86,15 @@ import { TalerErrorDetails, } from "@gnu-taler/taler-util"; import { CryptoApi } from "../../crypto/workers/cryptoApi.js"; -import { secretbox, secretbox_open } from "../../crypto/primitives/nacl-fast.js"; -import { checkPaymentByProposalId, confirmPay, preparePayForUri } from "../pay.js"; +import { + secretbox, + secretbox_open, +} from "../../crypto/primitives/nacl-fast.js"; +import { + checkPaymentByProposalId, + confirmPay, + preparePayForUri, +} from "../pay.js"; import { exportBackup } from "./export.js"; import { BackupCryptoPrecomputedData, importBackup } from "./import.js"; import { provideBackupState, getWalletBackupState } from "./state.js"; diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 1948f70e1..c8dfcbc17 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -60,7 +60,12 @@ import { WALLET_CACHE_BREAKER_CLIENT_VERSION, WALLET_EXCHANGE_PROTOCOL_VERSION, } from "./versions.js"; -import { getExpiryTimestamp, HttpRequestLibrary, readSuccessResponseJsonOrThrow, readSuccessResponseTextOrThrow } from "../util/http.js"; +import { + getExpiryTimestamp, + HttpRequestLibrary, + readSuccessResponseJsonOrThrow, + readSuccessResponseTextOrThrow, +} from "../util/http.js"; import { CryptoApi } from "../crypto/workers/cryptoApi.js"; import { DbAccess, GetReadOnlyAccess } from "../util/query.js"; import { decodeCrock, encodeCrock, hash } from "../crypto/talerCrypto.js"; diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index c442a7c90..3c81362ce 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -55,7 +55,10 @@ import { URL } from "../util/url.js"; import { guardOperationException } from "./errors.js"; import { updateExchangeFromUrl } from "./exchanges.js"; import { EXCHANGE_COINS_LOCK, InternalWalletState } from "./state.js"; -import { isWithdrawableDenom, selectWithdrawalDenominations } from "./withdraw.js"; +import { + isWithdrawableDenom, + selectWithdrawalDenominations, +} from "./withdraw.js"; import { RefreshNewDenomInfo } from "../crypto/cryptoTypes.js"; import { GetReadWriteAccess } from "../util/query.js"; diff --git a/packages/taler-wallet-core/src/operations/state.ts b/packages/taler-wallet-core/src/operations/state.ts index 66baa95a4..ee7ceb8af 100644 --- a/packages/taler-wallet-core/src/operations/state.ts +++ b/packages/taler-wallet-core/src/operations/state.ts @@ -27,8 +27,13 @@ import { WalletStoresV1 } from "../db.js"; import { PendingOperationsResponse } from "../pending-types.js"; import { AsyncOpMemoMap, AsyncOpMemoSingle } from "../util/asyncMemo.js"; import { HttpRequestLibrary } from "../util/http"; -import { OpenedPromise, openPromise } from "../util/promiseUtils.js"; +import { + AsyncCondition, + OpenedPromise, + openPromise, +} from "../util/promiseUtils.js"; import { DbAccess } from "../util/query.js"; +import { TimerGroup } from "../util/timer.js"; type NotificationListener = (n: WalletNotification) => void; @@ -37,6 +42,9 @@ const logger = new Logger("state.ts"); export const EXCHANGE_COINS_LOCK = "exchange-coins-lock"; export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock"; +/** + * Internal state of the wallet. + */ export class InternalWalletState { memoProcessReserve: AsyncOpMemoMap<void> = new AsyncOpMemoMap(); memoMakePlanchet: AsyncOpMemoMap<void> = new AsyncOpMemoMap(); @@ -47,8 +55,15 @@ export class InternalWalletState { memoProcessDeposit: AsyncOpMemoMap<void> = new AsyncOpMemoMap(); cryptoApi: CryptoApi; + timerGroup: TimerGroup = new TimerGroup(); + latch = new AsyncCondition(); + stopped = false; + memoRunRetryLoop = new AsyncOpMemoSingle<void>(); + listeners: NotificationListener[] = []; + initCalled: boolean = false; + /** * Promises that are waiting for a particular resource. */ @@ -86,6 +101,15 @@ export class InternalWalletState { } /** + * Stop ongoing processing. + */ + stop(): void { + this.stopped = true; + this.timerGroup.stopCurrentAndFutureTimers(); + this.cryptoApi.stop(); + } + + /** * Run an async function after acquiring a list of locks, identified * by string tokens. */ diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index b163569ae..ce3a47f36 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -33,10 +33,13 @@ import { TestPayArgs, PreparePayResultType, } from "@gnu-taler/taler-util"; -import { Wallet } from "../wallet.js"; import { createTalerWithdrawReserve } from "./reserves.js"; import { InternalWalletState } from "./state.js"; import { URL } from "../util/url.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"); @@ -261,14 +264,13 @@ interface BankWithdrawalResponse { } async function makePayment( - http: HttpRequestLibrary, - wallet: Wallet, + ws: InternalWalletState, merchant: MerchantBackendInfo, amount: string, summary: string, ): Promise<{ orderId: string }> { const orderResp = await createOrder( - http, + ws.http, merchant, amount, summary, @@ -277,7 +279,7 @@ async function makePayment( logger.trace("created order with orderId", orderResp.orderId); - let paymentStatus = await checkPayment(http, merchant, orderResp.orderId); + let paymentStatus = await checkPayment(ws.http, merchant, orderResp.orderId); logger.trace("payment status", paymentStatus); @@ -286,7 +288,7 @@ async function makePayment( throw Error("no taler://pay/ URI in payment response"); } - const preparePayResult = await wallet.preparePayForUri(talerPayUri); + const preparePayResult = await preparePayForUri(ws, talerPayUri); logger.trace("prepare pay result", preparePayResult); @@ -294,14 +296,15 @@ async function makePayment( throw Error("payment not possible"); } - const confirmPayResult = await wallet.confirmPay( + const confirmPayResult = await confirmPay( + ws, preparePayResult.proposalId, undefined, ); logger.trace("confirmPayResult", confirmPayResult); - paymentStatus = await checkPayment(http, merchant, orderResp.orderId); + paymentStatus = await checkPayment(ws.http, merchant, orderResp.orderId); logger.trace("payment status after wallet payment:", paymentStatus); @@ -315,8 +318,7 @@ async function makePayment( } export async function runIntegrationTest( - http: HttpRequestLibrary, - wallet: Wallet, + ws: InternalWalletState, args: IntegrationTestArgs, ): Promise<void> { logger.info("running test with arguments", args); @@ -325,15 +327,16 @@ export async function runIntegrationTest( const currency = parsedSpendAmount.currency; logger.info("withdrawing test balance"); - await wallet.withdrawTestBalance({ - amount: args.amountToWithdraw, - bankBaseUrl: args.bankBaseUrl, - exchangeBaseUrl: args.exchangeBaseUrl, - }); - await wallet.runUntilDone(); + await withdrawTestBalance( + ws, + args.amountToWithdraw, + args.bankBaseUrl, + args.exchangeBaseUrl, + ); + await runUntilDone(ws); logger.info("done withdrawing test balance"); - const balance = await wallet.getBalances(); + const balance = await getBalances(ws); logger.trace(JSON.stringify(balance, null, 2)); @@ -342,16 +345,10 @@ export async function runIntegrationTest( authToken: args.merchantAuthToken, }; - await makePayment( - http, - wallet, - myMerchant, - args.amountToSpend, - "hello world", - ); + await makePayment(ws, myMerchant, args.amountToSpend, "hello world"); // Wait until the refresh is done - await wallet.runUntilDone(); + await runUntilDone(ws); logger.trace("withdrawing test balance for refund"); const withdrawAmountTwo = Amounts.parseOrThrow(`${currency}:18`); @@ -359,25 +356,25 @@ export async function runIntegrationTest( const refundAmount = Amounts.parseOrThrow(`${currency}:6`); const spendAmountThree = Amounts.parseOrThrow(`${currency}:3`); - await wallet.withdrawTestBalance({ - amount: Amounts.stringify(withdrawAmountTwo), - bankBaseUrl: args.bankBaseUrl, - exchangeBaseUrl: args.exchangeBaseUrl, - }); + await withdrawTestBalance( + ws, + Amounts.stringify(withdrawAmountTwo), + args.bankBaseUrl, + args.exchangeBaseUrl, + ); // Wait until the withdraw is done - await wallet.runUntilDone(); + await runUntilDone(ws); const { orderId: refundOrderId } = await makePayment( - http, - wallet, + ws, myMerchant, Amounts.stringify(spendAmountTwo), "order that will be refunded", ); const refundUri = await refund( - http, + ws.http, myMerchant, refundOrderId, "test refund", @@ -386,18 +383,17 @@ export async function runIntegrationTest( logger.trace("refund URI", refundUri); - await wallet.applyRefund(refundUri); + await applyRefund(ws, refundUri); logger.trace("integration test: applied refund"); // Wait until the refund is done - await wallet.runUntilDone(); + await runUntilDone(ws); logger.trace("integration test: making payment after refund"); await makePayment( - http, - wallet, + ws, myMerchant, Amounts.stringify(spendAmountThree), "payment after refund", @@ -405,30 +401,26 @@ export async function runIntegrationTest( logger.trace("integration test: make payment done"); - await wallet.runUntilDone(); + await runUntilDone(ws); logger.trace("integration test: all done!"); } -export async function testPay( - http: HttpRequestLibrary, - wallet: Wallet, - args: TestPayArgs, -) { +export async function testPay(ws: InternalWalletState, args: TestPayArgs) { logger.trace("creating order"); const merchant = { authToken: args.merchantAuthToken, baseUrl: args.merchantBaseUrl, }; const orderResp = await createOrder( - http, + ws.http, merchant, args.amount, args.summary, "taler://fulfillment-success/thank+you", ); logger.trace("created new order with order ID", orderResp.orderId); - const checkPayResp = await checkPayment(http, merchant, orderResp.orderId); + const checkPayResp = await checkPayment(ws.http, merchant, orderResp.orderId); const talerPayUri = checkPayResp.taler_pay_uri; if (!talerPayUri) { console.error("fatal: no taler pay URI received from backend"); @@ -436,9 +428,9 @@ export async function testPay( return; } logger.trace("taler pay URI:", talerPayUri); - const result = await wallet.preparePayForUri(talerPayUri); + const result = await preparePayForUri(ws, talerPayUri); if (result.status !== PreparePayResultType.PaymentPossible) { throw Error(`unexpected prepare pay status: ${result.status}`); } - await wallet.confirmPay(result.proposalId, undefined); + await confirmPay(ws, result.proposalId, undefined); } diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 1b2c8477f..5836a6ee3 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -424,7 +424,7 @@ export async function retryTransaction( break; } case TransactionType.Payment: { - const proposalId = rest[0] + const proposalId = rest[0]; await processPurchasePay(ws, proposalId, true); break; } |