towards factoring out cyclic dependencies

This commit is contained in:
Florian Dold 2021-06-17 15:49:05 +02:00
parent 453656b240
commit a70d37ef16
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
28 changed files with 230 additions and 224 deletions

View File

@ -22,18 +22,18 @@ import {
BalancesResponse, BalancesResponse,
Logger, Logger,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { CryptoApi, CryptoWorkerFactory } from "../crypto/workers/cryptoApi.js"; import { CryptoApi, CryptoWorkerFactory } from "./crypto/workers/cryptoApi.js";
import { WalletStoresV1 } from "../db.js"; import { ExchangeDetailsRecord, ExchangeRecord, WalletStoresV1 } from "./db.js";
import { PendingOperationsResponse } from "../pending-types.js"; import { PendingOperationsResponse } from "./pending-types.js";
import { AsyncOpMemoMap, AsyncOpMemoSingle } from "../util/asyncMemo.js"; import { AsyncOpMemoMap, AsyncOpMemoSingle } from "./util/asyncMemo.js";
import { HttpRequestLibrary } from "../util/http"; import { HttpRequestLibrary } from "./util/http.js";
import { import {
AsyncCondition, AsyncCondition,
OpenedPromise, OpenedPromise,
openPromise, openPromise,
} from "../util/promiseUtils.js"; } from "./util/promiseUtils.js";
import { DbAccess } from "../util/query.js"; import { DbAccess, GetReadOnlyAccess } from "./util/query.js";
import { TimerGroup } from "../util/timer.js"; import { TimerGroup } from "./util/timer.js";
type NotificationListener = (n: WalletNotification) => void; type NotificationListener = (n: WalletNotification) => void;
@ -42,6 +42,38 @@ const logger = new Logger("state.ts");
export const EXCHANGE_COINS_LOCK = "exchange-coins-lock"; export const EXCHANGE_COINS_LOCK = "exchange-coins-lock";
export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock"; export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock";
export interface TrustInfo {
isTrusted: boolean;
isAudited: boolean;
}
/**
* Interface for exchange-related operations.
*/
export interface ExchangeOperations {
// FIXME: Should other operations maybe always use
// updateExchangeFromUrl?
getExchangeDetails(
tx: GetReadOnlyAccess<{
exchanges: typeof WalletStoresV1.exchanges;
exchangeDetails: typeof WalletStoresV1.exchangeDetails;
}>,
exchangeBaseUrl: string,
): Promise<ExchangeDetailsRecord | undefined>;
getExchangeTrust(
ws: InternalWalletState,
exchangeInfo: ExchangeRecord,
): Promise<TrustInfo>;
updateExchangeFromUrl(
ws: InternalWalletState,
baseUrl: string,
forceNow?: boolean,
): Promise<{
exchange: ExchangeRecord;
exchangeDetails: ExchangeDetailsRecord;
}>;
}
/** /**
* Internal state of the wallet. * Internal state of the wallet.
*/ */
@ -64,6 +96,8 @@ export class InternalWalletState {
initCalled: boolean = false; initCalled: boolean = false;
exchangeOps: ExchangeOperations;
/** /**
* Promises that are waiting for a particular resource. * Promises that are waiting for a particular resource.
*/ */

View File

@ -27,7 +27,7 @@ import {
} from "../util/http"; } from "../util/http";
import { RequestThrottler } from "../util/RequestThrottler"; import { RequestThrottler } from "../util/RequestThrottler";
import Axios, { AxiosResponse } from "axios"; import Axios, { AxiosResponse } from "axios";
import { OperationFailedError, makeErrorDetails } from "../operations/errors"; import { OperationFailedError, makeErrorDetails } from "../errors";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { Logger } from "@gnu-taler/taler-util"; import { Logger } from "@gnu-taler/taler-util";
import { bytesToString } from "../crypto/talerCrypto"; import { bytesToString } from "../crypto/talerCrypto";

View File

@ -35,7 +35,7 @@ import { Logger } from "@gnu-taler/taler-util";
import { SynchronousCryptoWorkerFactory } from "../crypto/workers/synchronousWorker"; import { SynchronousCryptoWorkerFactory } from "../crypto/workers/synchronousWorker";
import type { IDBFactory } from "@gnu-taler/idb-bridge"; import type { IDBFactory } from "@gnu-taler/idb-bridge";
import { WalletNotification } from "@gnu-taler/taler-util"; import { WalletNotification } from "@gnu-taler/taler-util";
import { InternalWalletState } from "../operations/state.js"; import { InternalWalletState } from "../common.js";
const logger = new Logger("headless/helpers.ts"); const logger = new Logger("headless/helpers.ts");

View File

@ -19,7 +19,7 @@
*/ */
// Errors // Errors
export * from "./operations/errors.js"; export * from "./errors.js";
// Util functionality // Util functionality
export { URL } from "./util/url.js"; export { URL } from "./util/url.js";
@ -34,7 +34,7 @@ export {
DefaultNodeWalletArgs, DefaultNodeWalletArgs,
} from "./headless/helpers.js"; } from "./headless/helpers.js";
export * from "./operations/versions.js"; export * from "./versions.js";
export * from "./db.js"; export * from "./db.js";
@ -48,6 +48,6 @@ export * from "./crypto/talerCrypto.js";
export * from "./pending-types.js"; export * from "./pending-types.js";
export * from "./util/debugFlags.js"; export * from "./util/debugFlags.js";
export { InternalWalletState } from "./operations/state.js"; export { InternalWalletState } from "./common.js";
export * from "./wallet-api-types.js"; export * from "./wallet-api-types.js";
export * from "./wallet.js"; export * from "./wallet.js";

View File

@ -0,0 +1,7 @@
# Wallet Operations
This folder contains the implementations for all wallet operations that operate on the wallet state.
To avoid cyclic dependencies, these files must **not** reference each other. Instead, other operations should only be accessed via injected dependencies.
Avoiding cyclic dependencies is important for module bundlers.

View File

@ -49,7 +49,7 @@ import {
BackupRefreshSession, BackupRefreshSession,
BackupExchangeDetails, BackupExchangeDetails,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { InternalWalletState } from "../state.js"; import { InternalWalletState } from "../../common.js";
import { provideBackupState, getWalletBackupState } from "./state"; import { provideBackupState, getWalletBackupState } from "./state";
import { Amounts, getTimestampNow } from "@gnu-taler/taler-util"; import { Amounts, getTimestampNow } from "@gnu-taler/taler-util";
import { import {

View File

@ -51,7 +51,7 @@ import { j2s } from "@gnu-taler/taler-util";
import { checkDbInvariant, checkLogicInvariant } from "../../util/invariants"; import { checkDbInvariant, checkLogicInvariant } from "../../util/invariants";
import { Logger } from "@gnu-taler/taler-util"; import { Logger } from "@gnu-taler/taler-util";
import { initRetryInfo } from "../../util/retries.js"; import { initRetryInfo } from "../../util/retries.js";
import { InternalWalletState } from "../state.js"; import { InternalWalletState } from "../../common.js";
import { provideBackupState } from "./state.js"; import { provideBackupState } from "./state.js";
import { makeEventId, TombstoneTag } from "../transactions.js"; import { makeEventId, TombstoneTag } from "../transactions.js";
import { getExchangeDetails } from "../exchanges.js"; import { getExchangeDetails } from "../exchanges.js";

View File

@ -24,7 +24,7 @@
/** /**
* Imports. * Imports.
*/ */
import { InternalWalletState } from "../state.js"; import { InternalWalletState } from "../../common.js";
import { import {
AmountString, AmountString,
BackupRecovery, BackupRecovery,

View File

@ -23,7 +23,7 @@ import {
} from "../../db.js"; } from "../../db.js";
import { checkDbInvariant } from "../../util/invariants.js"; import { checkDbInvariant } from "../../util/invariants.js";
import { GetReadOnlyAccess } from "../../util/query.js"; import { GetReadOnlyAccess } from "../../util/query.js";
import { InternalWalletState } from "../state.js"; import { InternalWalletState } from "../../common.js";
export async function provideBackupState( export async function provideBackupState(
ws: InternalWalletState, ws: InternalWalletState,

View File

@ -23,12 +23,11 @@ import {
Amounts, Amounts,
Logger, Logger,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { CoinStatus, WalletStoresV1 } from "../db.js"; import { CoinStatus, WalletStoresV1 } from "../db.js";
import { GetReadOnlyAccess } from "../util/query.js"; import { GetReadOnlyAccess } from "../util/query.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
const logger = new Logger("withdraw.ts"); const logger = new Logger("operations/balance.ts");
interface WalletBalance { interface WalletBalance {
available: AmountJson; available: AmountJson;

View File

@ -1,81 +0,0 @@
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* Imports.
*/
import { ExchangeRecord } from "../db.js";
import { Logger } from "@gnu-taler/taler-util";
import { getExchangeDetails } from "./exchanges.js";
import { InternalWalletState } from "./state.js";
const logger = new Logger("currencies.ts");
export interface TrustInfo {
isTrusted: boolean;
isAudited: boolean;
}
/**
* Check if and how an exchange is trusted and/or audited.
*/
export async function getExchangeTrust(
ws: InternalWalletState,
exchangeInfo: ExchangeRecord,
): Promise<TrustInfo> {
let isTrusted = false;
let isAudited = false;
return await ws.db
.mktx((x) => ({
exchanges: x.exchanges,
exchangeDetails: x.exchangeDetails,
exchangesTrustStore: x.exchangeTrust,
auditorTrust: x.auditorTrust,
}))
.runReadOnly(async (tx) => {
const exchangeDetails = await getExchangeDetails(
tx,
exchangeInfo.baseUrl,
);
if (!exchangeDetails) {
throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
}
const exchangeTrustRecord = await tx.exchangesTrustStore.indexes.byExchangeMasterPub.get(
exchangeDetails.masterPublicKey,
);
if (
exchangeTrustRecord &&
exchangeTrustRecord.uids.length > 0 &&
exchangeTrustRecord.currency === exchangeDetails.currency
) {
isTrusted = true;
}
for (const auditor of exchangeDetails.auditors) {
const auditorTrustRecord = await tx.auditorTrust.indexes.byAuditorPub.get(
auditor.auditor_pub,
);
if (auditorTrustRecord && auditorTrustRecord.uids.length > 0) {
isAudited = true;
break;
}
}
return { isTrusted, isAudited };
});
}

View File

@ -14,19 +14,10 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { kdf } from "../crypto/primitives/kdf.js";
import {
encodeCrock,
getRandomBytes,
stringToBytes,
} from "../crypto/talerCrypto.js";
import { selectPayCoins } from "../util/coinSelection.js";
import { canonicalJson } from "@gnu-taler/taler-util";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { import {
Amounts, Amounts,
buildCodecForObject, buildCodecForObject,
canonicalJson,
Codec, Codec,
codecForString, codecForString,
codecForTimestamp, codecForTimestamp,
@ -36,6 +27,7 @@ import {
CreateDepositGroupResponse, CreateDepositGroupResponse,
durationFromSpec, durationFromSpec,
getTimestampNow, getTimestampNow,
Logger,
NotificationType, NotificationType,
parsePaytoUri, parsePaytoUri,
TalerErrorDetails, TalerErrorDetails,
@ -45,7 +37,20 @@ import {
TrackDepositGroupRequest, TrackDepositGroupRequest,
TrackDepositGroupResponse, TrackDepositGroupResponse,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { URL } from "../util/url"; import { InternalWalletState } from "../common.js";
import { kdf } from "../crypto/primitives/kdf.js";
import {
encodeCrock,
getRandomBytes,
stringToBytes,
} from "../crypto/talerCrypto.js";
import { DepositGroupRecord } from "../db.js";
import { guardOperationException } from "../errors.js";
import { selectPayCoins } from "../util/coinSelection.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { URL } from "../util/url.js";
import { getExchangeDetails } from "./exchanges.js";
import { import {
applyCoinSpend, applyCoinSpend,
extractContractData, extractContractData,
@ -54,12 +59,6 @@ import {
getEffectiveDepositAmount, getEffectiveDepositAmount,
getTotalPaymentCost, getTotalPaymentCost,
} from "./pay.js"; } from "./pay.js";
import { InternalWalletState } from "./state.js";
import { Logger } from "@gnu-taler/taler-util";
import { DepositGroupRecord } from "../db.js";
import { guardOperationException } from "./errors.js";
import { getExchangeDetails } from "./exchanges.js";
/** /**
* Logger. * Logger.

View File

@ -20,6 +20,7 @@
import { import {
Amounts, Amounts,
Auditor, Auditor,
canonicalizeBaseUrl,
codecForExchangeKeysJson, codecForExchangeKeysJson,
codecForExchangeWireJson, codecForExchangeWireJson,
compare, compare,
@ -30,6 +31,7 @@ import {
ExchangeWireJson, ExchangeWireJson,
getTimestampNow, getTimestampNow,
isTimestampExpired, isTimestampExpired,
j2s,
Logger, Logger,
NotificationType, NotificationType,
parsePaytoUri, parsePaytoUri,
@ -38,38 +40,37 @@ import {
TalerErrorDetails, TalerErrorDetails,
Timestamp, Timestamp,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { decodeCrock, encodeCrock, hash } from "../crypto/talerCrypto.js";
import { CryptoApi } from "../crypto/workers/cryptoApi.js";
import { import {
DenominationRecord, DenominationRecord,
DenominationStatus, DenominationStatus,
ExchangeRecord,
WireFee,
ExchangeDetailsRecord, ExchangeDetailsRecord,
WireInfo, ExchangeRecord,
WalletStoresV1, WalletStoresV1,
WireFee,
WireInfo,
} from "../db.js"; } from "../db.js";
import { j2s, canonicalizeBaseUrl } from "@gnu-taler/taler-util";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries.js";
import {
makeErrorDetails,
guardOperationException,
OperationFailedError,
} from "./errors.js";
import { createRecoupGroup, processRecoupGroup } from "./recoup.js";
import { InternalWalletState } from "./state.js";
import {
WALLET_CACHE_BREAKER_CLIENT_VERSION,
WALLET_EXCHANGE_PROTOCOL_VERSION,
} from "./versions.js";
import { import {
getExpiryTimestamp, getExpiryTimestamp,
HttpRequestLibrary, HttpRequestLibrary,
readSuccessResponseJsonOrThrow, readSuccessResponseJsonOrThrow,
readSuccessResponseTextOrThrow, readSuccessResponseTextOrThrow,
} from "../util/http.js"; } from "../util/http.js";
import { CryptoApi } from "../crypto/workers/cryptoApi.js";
import { DbAccess, GetReadOnlyAccess } from "../util/query.js"; import { DbAccess, GetReadOnlyAccess } from "../util/query.js";
import { decodeCrock, encodeCrock, hash } from "../crypto/talerCrypto.js"; import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { URL } from "../util/url.js"; import { URL } from "../util/url.js";
import {
guardOperationException,
makeErrorDetails,
OperationFailedError,
} from "../errors.js";
import { createRecoupGroup, processRecoupGroup } from "./recoup.js";
import { InternalWalletState, TrustInfo } from "../common.js";
import {
WALLET_CACHE_BREAKER_CLIENT_VERSION,
WALLET_EXCHANGE_PROTOCOL_VERSION,
} from "../versions.js";
const logger = new Logger("exchanges.ts"); const logger = new Logger("exchanges.ts");
@ -605,3 +606,54 @@ export async function getExchangePaytoUri(
} }
throw Error("no matching exchange account found"); throw Error("no matching exchange account found");
} }
/**
* Check if and how an exchange is trusted and/or audited.
*/
export async function getExchangeTrust(
ws: InternalWalletState,
exchangeInfo: ExchangeRecord,
): Promise<TrustInfo> {
let isTrusted = false;
let isAudited = false;
return await ws.db
.mktx((x) => ({
exchanges: x.exchanges,
exchangeDetails: x.exchangeDetails,
exchangesTrustStore: x.exchangeTrust,
auditorTrust: x.auditorTrust,
}))
.runReadOnly(async (tx) => {
const exchangeDetails = await getExchangeDetails(
tx,
exchangeInfo.baseUrl,
);
if (!exchangeDetails) {
throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
}
const exchangeTrustRecord = await tx.exchangesTrustStore.indexes.byExchangeMasterPub.get(
exchangeDetails.masterPublicKey,
);
if (
exchangeTrustRecord &&
exchangeTrustRecord.uids.length > 0 &&
exchangeTrustRecord.currency === exchangeDetails.currency
) {
isTrusted = true;
}
for (const auditor of exchangeDetails.auditors) {
const auditorTrustRecord = await tx.auditorTrust.indexes.byAuditorPub.get(
auditor.auditor_pub,
);
if (auditorTrustRecord && auditorTrustRecord.uids.length > 0) {
isAudited = true;
break;
}
}
return { isTrusted, isAudited };
});
}

View File

@ -68,7 +68,7 @@ import {
getRetryDuration, getRetryDuration,
} from "../util/retries.js"; } from "../util/retries.js";
import { getTotalRefreshCost, createRefreshGroup } from "./refresh.js"; import { getTotalRefreshCost, createRefreshGroup } from "./refresh.js";
import { InternalWalletState, EXCHANGE_COINS_LOCK } from "./state.js"; import { InternalWalletState, EXCHANGE_COINS_LOCK } from "../common.js";
import { ContractTermsUtil } from "../util/contractTerms.js"; import { ContractTermsUtil } from "../util/contractTerms.js";
import { getExchangeDetails } from "./exchanges.js"; import { getExchangeDetails } from "./exchanges.js";
import { GetReadWriteAccess } from "../util/query.js"; import { GetReadWriteAccess } from "../util/query.js";
@ -98,7 +98,7 @@ import {
makeErrorDetails, makeErrorDetails,
OperationFailedAndReportedError, OperationFailedAndReportedError,
OperationFailedError, OperationFailedError,
} from "./errors.js"; } from "../errors.js";
import { URL } from "../util/url.js"; import { URL } from "../util/url.js";
/** /**

View File

@ -29,7 +29,7 @@ import {
ReserveType, ReserveType,
} from "../pending-types.js"; } from "../pending-types.js";
import { getTimestampNow, Timestamp } from "@gnu-taler/taler-util"; import { getTimestampNow, Timestamp } from "@gnu-taler/taler-util";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { getBalancesInsideTransaction } from "./balance.js"; import { getBalancesInsideTransaction } from "./balance.js";
import { GetReadOnlyAccess } from "../util/query.js"; import { GetReadOnlyAccess } from "../util/query.js";

View File

@ -48,10 +48,10 @@ import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { Logger } from "@gnu-taler/taler-util"; import { Logger } from "@gnu-taler/taler-util";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js"; import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { URL } from "../util/url.js"; import { URL } from "../util/url.js";
import { guardOperationException } from "./errors.js"; import { guardOperationException } from "../errors.js";
import { createRefreshGroup, processRefreshGroup } from "./refresh.js"; import { createRefreshGroup, processRefreshGroup } from "./refresh.js";
import { getReserveRequestTimeout, processReserve } from "./reserves.js"; import { getReserveRequestTimeout, processReserve } from "./reserves.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { GetReadWriteAccess } from "../util/query.js"; import { GetReadWriteAccess } from "../util/query.js";
const logger = new Logger("operations/recoup.ts"); const logger = new Logger("operations/recoup.ts");

View File

@ -52,9 +52,9 @@ import {
timestampMin, timestampMin,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { URL } from "../util/url.js"; import { URL } from "../util/url.js";
import { guardOperationException } from "./errors.js"; import { guardOperationException } from "../errors.js";
import { updateExchangeFromUrl } from "./exchanges.js"; import { updateExchangeFromUrl } from "./exchanges.js";
import { EXCHANGE_COINS_LOCK, InternalWalletState } from "./state.js"; import { EXCHANGE_COINS_LOCK, InternalWalletState } from "../common.js";
import { import {
isWithdrawableDenom, isWithdrawableDenom,
selectWithdrawalDenominations, selectWithdrawalDenominations,

View File

@ -23,12 +23,7 @@
/** /**
* Imports. * Imports.
*/ */
import { InternalWalletState } from "./state.js";
import { guardOperationException } from "./errors.js";
import { import {
getTimestampNow,
timestampAddDuration,
TalerErrorDetails,
AbortingCoin, AbortingCoin,
AbortRequest, AbortRequest,
AmountJson, AmountJson,
@ -37,29 +32,34 @@ import {
codecForAbortResponse, codecForAbortResponse,
codecForMerchantOrderRefundPickupResponse, codecForMerchantOrderRefundPickupResponse,
CoinPublicKey, CoinPublicKey,
getTimestampNow,
Logger,
MerchantCoinRefundFailureStatus, MerchantCoinRefundFailureStatus,
MerchantCoinRefundStatus, MerchantCoinRefundStatus,
MerchantCoinRefundSuccessStatus, MerchantCoinRefundSuccessStatus,
NotificationType, NotificationType,
parseRefundUri, parseRefundUri,
RefreshReason, RefreshReason,
TalerErrorCode,
TalerErrorDetails,
timestampAddDuration,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Logger } from "@gnu-taler/taler-util";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { URL } from "../util/url.js";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries.js";
import { checkDbInvariant } from "../util/invariants.js";
import { TalerErrorCode } from "@gnu-taler/taler-util";
import { import {
PurchaseRecord,
CoinStatus,
RefundState,
AbortStatus, AbortStatus,
CoinStatus,
PurchaseRecord,
RefundReason, RefundReason,
RefundState,
WalletStoresV1, WalletStoresV1,
} from "../db.js"; } from "../db.js";
import { getTotalRefreshCost, createRefreshGroup } from "./refresh.js"; import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { checkDbInvariant } from "../util/invariants.js";
import { GetReadWriteAccess } from "../util/query.js"; import { GetReadWriteAccess } from "../util/query.js";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { URL } from "../util/url.js";
import { guardOperationException } from "../errors.js";
import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
import { InternalWalletState } from "../common.js";
const logger = new Logger("refund.ts"); const logger = new Logger("refund.ts");

View File

@ -47,13 +47,14 @@ import {
getRetryDuration, getRetryDuration,
updateRetryInfoTimeout, updateRetryInfoTimeout,
} from "../util/retries.js"; } from "../util/retries.js";
import { guardOperationException, OperationFailedError } from "./errors.js"; import { guardOperationException, OperationFailedError } from "../errors.js";
import { import {
updateExchangeFromUrl, updateExchangeFromUrl,
getExchangePaytoUri, getExchangePaytoUri,
getExchangeDetails, getExchangeDetails,
getExchangeTrust,
} from "./exchanges.js"; } from "./exchanges.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { import {
updateWithdrawalDenoms, updateWithdrawalDenoms,
getCandidateWithdrawalDenoms, getCandidateWithdrawalDenoms,
@ -62,7 +63,6 @@ import {
processWithdrawGroup, processWithdrawGroup,
getBankWithdrawalInfo, getBankWithdrawalInfo,
} from "./withdraw.js"; } from "./withdraw.js";
import { getExchangeTrust } from "./currencies.js";
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
import { Logger } from "@gnu-taler/taler-util"; import { Logger } from "@gnu-taler/taler-util";
import { import {

View File

@ -34,7 +34,7 @@ import {
PreparePayResultType, PreparePayResultType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { createTalerWithdrawReserve } from "./reserves.js"; import { createTalerWithdrawReserve } from "./reserves.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { URL } from "../util/url.js"; import { URL } from "../util/url.js";
import { confirmPay, preparePayForUri } from "./pay.js"; import { confirmPay, preparePayForUri } from "./pay.js";
import { getBalances } from "./balance.js"; import { getBalances } from "./balance.js";

View File

@ -40,9 +40,9 @@ import {
import { j2s } from "@gnu-taler/taler-util"; import { j2s } from "@gnu-taler/taler-util";
import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js"; import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js"; import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { guardOperationException, makeErrorDetails } from "./errors.js"; import { guardOperationException, makeErrorDetails } from "../errors.js";
import { updateExchangeFromUrl } from "./exchanges.js"; import { updateExchangeFromUrl } from "./exchanges.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { import {
getExchangeWithdrawalInfo, getExchangeWithdrawalInfo,
updateWithdrawalDenoms, updateWithdrawalDenoms,

View File

@ -17,7 +17,7 @@
/** /**
* Imports. * Imports.
*/ */
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "../common.js";
import { import {
WalletRefundItem, WalletRefundItem,
RefundState, RefundState,

View File

@ -17,65 +17,56 @@
/** /**
* Imports. * Imports.
*/ */
import * as LibtoolVersion from "@gnu-taler/taler-util";
import { import {
AmountJson, AmountJson,
Amounts, Amounts,
durationFromSpec,
parseWithdrawUri,
Timestamp,
} from "@gnu-taler/taler-util";
import {
DenominationRecord,
DenominationStatus,
CoinStatus,
CoinRecord,
CoinSourceType,
DenominationSelectionInfo,
PlanchetRecord,
DenomSelectionState,
ExchangeRecord,
ExchangeDetailsRecord,
} from "../db.js";
import {
BankWithdrawDetails, BankWithdrawDetails,
TalerErrorDetails, codecForTalerConfigResponse,
codecForWithdrawOperationStatusResponse,
codecForWithdrawResponse,
compare,
durationFromSpec,
ExchangeListItem, ExchangeListItem,
getDurationRemaining,
getTimestampNow,
Logger,
NotificationType,
parseWithdrawUri,
TalerErrorCode,
TalerErrorDetails,
Timestamp,
timestampCmp,
timestampSubtractDuraction,
WithdrawResponse,
WithdrawUriInfoResponse, WithdrawUriInfoResponse,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
codecForWithdrawOperationStatusResponse, CoinRecord,
codecForWithdrawResponse, CoinSourceType,
WithdrawResponse, CoinStatus,
codecForTalerConfigResponse, DenominationRecord,
} from "@gnu-taler/taler-util"; DenominationSelectionInfo,
import { InternalWalletState } from "./state.js"; DenominationStatus,
import { Logger } from "@gnu-taler/taler-util"; DenomSelectionState,
import { getExchangeDetails, updateExchangeFromUrl } from "./exchanges.js"; ExchangeDetailsRecord,
import { ExchangeRecord,
WALLET_EXCHANGE_PROTOCOL_VERSION, PlanchetRecord,
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION, } from "../db.js";
} from "./versions.js"; import { walletCoreDebugFlags } from "../util/debugFlags.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import * as LibtoolVersion from "@gnu-taler/taler-util"; import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";
import { URL } from "../util/url.js";
import { import {
guardOperationException, guardOperationException,
makeErrorDetails, makeErrorDetails,
OperationFailedError, OperationFailedError,
} from "./errors.js"; } from "../errors.js";
import { NotificationType } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../common.js";
import { import {
getTimestampNow, WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
getDurationRemaining, WALLET_EXCHANGE_PROTOCOL_VERSION,
timestampCmp, } from "../versions.js";
timestampSubtractDuraction,
} from "@gnu-taler/taler-util";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { URL } from "../util/url.js";
import { TalerErrorCode } from "@gnu-taler/taler-util";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries.js";
import { compare } from "@gnu-taler/taler-util";
import { walletCoreDebugFlags } from "../util/debugFlags.js";
import { getExchangeTrust } from "./currencies.js";
/** /**
* Logger for this file. * Logger for this file.
@ -690,7 +681,7 @@ export async function updateWithdrawalDenoms(
exchangeDetails: x.exchangeDetails, exchangeDetails: x.exchangeDetails,
})) }))
.runReadOnly(async (tx) => { .runReadOnly(async (tx) => {
return getExchangeDetails(tx, exchangeBaseUrl); return ws.exchangeOps.getExchangeDetails(tx, exchangeBaseUrl);
}); });
if (!exchangeDetails) { if (!exchangeDetails) {
logger.error("exchange details not available"); logger.error("exchange details not available");
@ -816,7 +807,10 @@ async function processWithdrawGroupImpl(
return; return;
} }
await updateExchangeFromUrl(ws, withdrawalGroup.exchangeBaseUrl); await ws.exchangeOps.updateExchangeFromUrl(
ws,
withdrawalGroup.exchangeBaseUrl,
);
const numTotalCoins = withdrawalGroup.denomsSel.selectedDenoms const numTotalCoins = withdrawalGroup.denomsSel.selectedDenoms
.map((x) => x.count) .map((x) => x.count)
@ -910,10 +904,10 @@ export async function getExchangeWithdrawalInfo(
baseUrl: string, baseUrl: string,
amount: AmountJson, amount: AmountJson,
): Promise<ExchangeWithdrawDetails> { ): Promise<ExchangeWithdrawDetails> {
const { exchange, exchangeDetails } = await updateExchangeFromUrl( const {
ws, exchange,
baseUrl, exchangeDetails,
); } = await ws.exchangeOps.updateExchangeFromUrl(ws, baseUrl);
await updateWithdrawalDenoms(ws, baseUrl); await updateWithdrawalDenoms(ws, baseUrl);
const denoms = await getCandidateWithdrawalDenoms(ws, baseUrl); const denoms = await getCandidateWithdrawalDenoms(ws, baseUrl);
const selectedDenoms = selectWithdrawalDenominations(amount, denoms); const selectedDenoms = selectWithdrawalDenominations(amount, denoms);
@ -922,7 +916,10 @@ export async function getExchangeWithdrawalInfo(
exchangeWireAccounts.push(account.payto_uri); exchangeWireAccounts.push(account.payto_uri);
} }
const { isTrusted, isAudited } = await getExchangeTrust(ws, exchange); const { isTrusted, isAudited } = await ws.exchangeOps.getExchangeTrust(
ws,
exchange,
);
let earliestDepositExpiration = let earliestDepositExpiration =
selectedDenoms.selectedDenoms[0].denom.stampExpireDeposit; selectedDenoms.selectedDenoms[0].denom.stampExpireDeposit;
@ -1009,7 +1006,7 @@ export async function getWithdrawalDetailsForUri(
// FIXME: right now the exchange gets permanently added, // FIXME: right now the exchange gets permanently added,
// we might want to only temporarily add it. // we might want to only temporarily add it.
try { try {
await updateExchangeFromUrl(ws, info.suggestedExchange); await ws.exchangeOps.updateExchangeFromUrl(ws, info.suggestedExchange);
} catch (e) { } catch (e) {
// We still continued if it failed, as other exchanges might be available. // We still continued if it failed, as other exchanges might be available.
// We don't want to fail if the bank-suggested exchange is broken/offline. // We don't want to fail if the bank-suggested exchange is broken/offline.
@ -1029,7 +1026,7 @@ export async function getWithdrawalDetailsForUri(
.runReadOnly(async (tx) => { .runReadOnly(async (tx) => {
const exchangeRecords = await tx.exchanges.iter().toArray(); const exchangeRecords = await tx.exchanges.iter().toArray();
for (const r of exchangeRecords) { for (const r of exchangeRecords) {
const details = await getExchangeDetails(tx, r.baseUrl); const details = await ws.exchangeOps.getExchangeDetails(tx, r.baseUrl);
if (details) { if (details) {
exchanges.push({ exchanges.push({
exchangeBaseUrl: details.exchangeBaseUrl, exchangeBaseUrl: details.exchangeBaseUrl,

View File

@ -27,7 +27,6 @@
import { import {
TalerErrorDetails, TalerErrorDetails,
BalancesResponse, BalancesResponse,
Duration,
Timestamp, Timestamp,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { ReserveRecordStatus } from "./db.js"; import { ReserveRecordStatus } from "./db.js";

View File

@ -27,7 +27,7 @@
import { import {
OperationFailedError, OperationFailedError,
makeErrorDetails, makeErrorDetails,
} from "../operations/errors.js"; } from "../errors.js";
import { import {
Logger, Logger,
Duration, Duration,

View File

@ -55,7 +55,7 @@ import {
makeErrorDetails, makeErrorDetails,
OperationFailedAndReportedError, OperationFailedAndReportedError,
OperationFailedError, OperationFailedError,
} from "./operations/errors"; } from "./errors";
import { import {
acceptExchangeTermsOfService, acceptExchangeTermsOfService,
getExchangeDetails, getExchangeDetails,
@ -85,7 +85,7 @@ import {
getFundingPaytoUris, getFundingPaytoUris,
processReserve, processReserve,
} from "./operations/reserves"; } from "./operations/reserves";
import { InternalWalletState } from "./operations/state"; import { InternalWalletState } from "./common";
import { import {
runIntegrationTest, runIntegrationTest,
testPay, testPay,