towards factoring out cyclic dependencies
This commit is contained in:
parent
453656b240
commit
a70d37ef16
packages/taler-wallet-core/src
@ -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.
|
||||||
*/
|
*/
|
@ -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";
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
7
packages/taler-wallet-core/src/operations/README.md
Normal file
7
packages/taler-wallet-core/src/operations/README.md
Normal 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.
|
@ -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 {
|
||||||
|
@ -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";
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { InternalWalletState } from "../state.js";
|
import { InternalWalletState } from "../../common.js";
|
||||||
import {
|
import {
|
||||||
AmountString,
|
AmountString,
|
||||||
BackupRecovery,
|
BackupRecovery,
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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 };
|
|
||||||
});
|
|
||||||
}
|
|
@ -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.
|
||||||
|
@ -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 };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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,
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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";
|
||||||
|
@ -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,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { InternalWalletState } from "./state.js";
|
import { InternalWalletState } from "../common.js";
|
||||||
import {
|
import {
|
||||||
WalletRefundItem,
|
WalletRefundItem,
|
||||||
RefundState,
|
RefundState,
|
||||||
|
@ -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,
|
||||||
|
@ -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";
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
import {
|
import {
|
||||||
OperationFailedError,
|
OperationFailedError,
|
||||||
makeErrorDetails,
|
makeErrorDetails,
|
||||||
} from "../operations/errors.js";
|
} from "../errors.js";
|
||||||
import {
|
import {
|
||||||
Logger,
|
Logger,
|
||||||
Duration,
|
Duration,
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user