aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-wallet-core/src/attention.ts2
-rw-r--r--packages/taler-wallet-core/src/dbless.ts33
-rw-r--r--packages/taler-wallet-core/src/deposits.ts12
-rw-r--r--packages/taler-wallet-core/src/exchanges.ts20
-rw-r--r--packages/taler-wallet-core/src/host-impl.node.ts9
-rw-r--r--packages/taler-wallet-core/src/index.ts35
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts10
-rw-r--r--packages/taler-wallet-core/src/pay-peer-pull-credit.ts4
-rw-r--r--packages/taler-wallet-core/src/pay-peer-pull-debit.ts9
-rw-r--r--packages/taler-wallet-core/src/pay-peer-push-credit.ts6
-rw-r--r--packages/taler-wallet-core/src/pay-peer-push-debit.ts4
-rw-r--r--packages/taler-wallet-core/src/refresh.ts10
-rw-r--r--packages/taler-wallet-core/src/shepherd.ts6
-rw-r--r--packages/taler-wallet-core/src/testing.ts6
-rw-r--r--packages/taler-wallet-core/src/transactions.ts14
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.ts11
-rw-r--r--packages/taler-wallet-core/src/util/denominations.ts3
-rw-r--r--packages/taler-wallet-core/src/util/instructedAmountConversion.ts9
-rw-r--r--packages/taler-wallet-core/src/withdraw.ts220
19 files changed, 231 insertions, 192 deletions
diff --git a/packages/taler-wallet-core/src/attention.ts b/packages/taler-wallet-core/src/attention.ts
index 3be1f7197..6893af010 100644
--- a/packages/taler-wallet-core/src/attention.ts
+++ b/packages/taler-wallet-core/src/attention.ts
@@ -28,7 +28,7 @@ import {
UserAttentionsRequest,
UserAttentionsResponse,
} from "@gnu-taler/taler-util";
-import { timestampPreciseFromDb, timestampPreciseToDb } from "./index.js";
+import { timestampPreciseFromDb, timestampPreciseToDb } from "./db.js";
import { InternalWalletState } from "./internal-wallet-state.js";
const logger = new Logger("operations/attention.ts");
diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts
index 968d3b958..e538a6e76 100644
--- a/packages/taler-wallet-core/src/dbless.ts
+++ b/packages/taler-wallet-core/src/dbless.ts
@@ -29,29 +29,26 @@ import {
AbsoluteTime,
AgeRestriction,
AmountJson,
- Amounts,
AmountString,
+ Amounts,
+ DenominationPubKey,
+ ExchangeBatchDepositRequest,
+ ExchangeBatchWithdrawRequest,
+ ExchangeMeltRequest,
+ ExchangeProtocolVersion,
+ Logger,
TalerCorebankApiClient,
+ UnblindedSignature,
codecForAny,
codecForBankWithdrawalOperationPostResponse,
codecForBatchDepositSuccess,
codecForExchangeMeltResponse,
codecForExchangeRevealResponse,
- codecForWithdrawResponse,
- DenominationPubKey,
+ codecForExchangeWithdrawBatchResponse,
encodeCrock,
- ExchangeBatchDepositRequest,
- ExchangeMeltRequest,
- ExchangeProtocolVersion,
- ExchangeWithdrawRequest,
getRandomBytes,
hashWire,
- Logger,
parsePaytoUri,
- UnblindedSignature,
- ExchangeBatchWithdrawRequest,
- ExchangeWithdrawBatchResponse,
- codecForExchangeWithdrawBatchResponse,
} from "@gnu-taler/taler-util";
import {
HttpRequestLibrary,
@@ -59,16 +56,10 @@ import {
} from "@gnu-taler/taler-util/http";
import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js";
import { DenominationRecord } from "./db.js";
-import {
- ExchangeInfo,
- ExchangeKeysDownloadResult,
- isWithdrawableDenom,
-} from "./index.js";
+import { ExchangeInfo } from "./exchanges.js";
import { assembleRefreshRevealRequest } from "./refresh.js";
-import {
- getBankStatusUrl,
- getBankWithdrawalInfo,
-} from "./withdraw.js";
+import { isWithdrawableDenom } from "./util/denominations.js";
+import { getBankStatusUrl, getBankWithdrawalInfo } from "./withdraw.js";
const logger = new Logger("dbless.ts");
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
index b6cfa7aae..906503430 100644
--- a/packages/taler-wallet-core/src/deposits.ts
+++ b/packages/taler-wallet-core/src/deposits.ts
@@ -78,25 +78,24 @@ import {
constructTaskIdentifier,
spendCoins,
} from "./common.js";
-import { DepositElementStatus, DepositGroupRecord } from "./db.js";
-import { getExchangeWireDetailsInTx } from "./exchanges.js";
import {
+ DepositElementStatus,
+ DepositGroupRecord,
DepositOperationStatus,
DepositTrackingInfo,
KycPendingInfo,
RefreshOperationStatus,
- createRefreshGroup,
- getCandidateWithdrawalDenomsTx,
- getTotalRefreshCost,
timestampPreciseToDb,
timestampProtocolToDb,
-} from "./index.js";
+} from "./db.js";
+import { getExchangeWireDetailsInTx } from "./exchanges.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import {
extractContractData,
generateDepositPermissions,
getTotalPaymentCost,
} from "./pay-merchant.js";
+import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
import {
constructTransactionIdentifier,
notifyTransition,
@@ -105,6 +104,7 @@ import {
import { assertUnreachable } from "./util/assertUnreachable.js";
import { selectPayCoinsNew } from "./util/coinSelection.js";
import { checkDbInvariant, checkLogicInvariant } from "./util/invariants.js";
+import { getCandidateWithdrawalDenomsTx } from "./withdraw.js";
/**
* Logger.
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
index 0f080b871..2c15691aa 100644
--- a/packages/taler-wallet-core/src/exchanges.ts
+++ b/packages/taler-wallet-core/src/exchanges.ts
@@ -104,28 +104,28 @@ import {
DenominationRecord,
DenominationVerificationStatus,
ExchangeDetailsRecord,
- ExchangeEntryRecord,
- WalletStoresV1,
-} from "./db.js";
-import {
ExchangeEntryDbRecordStatus,
ExchangeEntryDbUpdateStatus,
+ ExchangeEntryRecord,
WalletDbReadOnlyTransaction,
WalletDbReadWriteTransaction,
- createRefreshGroup,
- createTimeline,
- isWithdrawableDenom,
- selectBestForOverlappingDenominations,
- selectMinimumFee,
+ WalletStoresV1,
timestampAbsoluteFromDb,
timestampOptionalPreciseFromDb,
timestampPreciseFromDb,
timestampPreciseToDb,
timestampProtocolFromDb,
timestampProtocolToDb,
-} from "./index.js";
+} from "./db.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import { DbReadOnlyTransaction } from "./query.js";
+import { createRefreshGroup } from "./refresh.js";
+import {
+ createTimeline,
+ isWithdrawableDenom,
+ selectBestForOverlappingDenominations,
+ selectMinimumFee,
+} from "./util/denominations.js";
import { checkDbInvariant } from "./util/invariants.js";
import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "./versions.js";
diff --git a/packages/taler-wallet-core/src/host-impl.node.ts b/packages/taler-wallet-core/src/host-impl.node.ts
index 622ea742e..a2c37b32b 100644
--- a/packages/taler-wallet-core/src/host-impl.node.ts
+++ b/packages/taler-wallet-core/src/host-impl.node.ts
@@ -25,22 +25,21 @@
import type { IDBFactory } from "@gnu-taler/idb-bridge";
// eslint-disable-next-line no-duplicate-imports
import {
+ AccessStats,
BridgeIDBFactory,
MemoryBackend,
createSqliteBackend,
shimIndexedDB,
} from "@gnu-taler/idb-bridge";
-import { AccessStats } from "@gnu-taler/idb-bridge";
+import { createNodeSqlite3Impl } from "@gnu-taler/idb-bridge/node-sqlite3-bindings";
import { Logger } from "@gnu-taler/taler-util";
+import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
import * as fs from "fs";
import { NodeThreadCryptoWorkerFactory } from "./crypto/workers/nodeThreadWorker.js";
import { SynchronousCryptoWorkerFactoryPlain } from "./crypto/workers/synchronousWorkerFactoryPlain.js";
-import { openTalerDatabase } from "./index.js";
-import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
+import { DefaultNodeWalletArgs, makeTempfileId } from "./host-common.js";
import { SetTimeoutTimerAPI } from "./util/timer.js";
import { Wallet } from "./wallet.js";
-import { DefaultNodeWalletArgs, makeTempfileId } from "./host-common.js";
-import { createNodeSqlite3Impl } from "@gnu-taler/idb-bridge/node-sqlite3-bindings";
const logger = new Logger("host-impl.node.ts");
diff --git a/packages/taler-wallet-core/src/index.ts b/packages/taler-wallet-core/src/index.ts
index 2b619be69..0e1feb58f 100644
--- a/packages/taler-wallet-core/src/index.ts
+++ b/packages/taler-wallet-core/src/index.ts
@@ -18,40 +18,17 @@
* Module entry point for the wallet when used as a node module.
*/
-// Util functionality
-export * from "./query.js";
-
-export * from "./versions.js";
-
-export * from "./db.js";
-
-// Crypto and crypto workers
-// export * from "./crypto/workers/nodeThreadWorker.js";
+export * from "./crypto/cryptoImplementation.js";
+export * from "./crypto/cryptoTypes.js";
export {
CryptoDispatcher,
CryptoWorkerFactory,
} from "./crypto/workers/crypto-dispatcher.js";
export type { CryptoWorker } from "./crypto/workers/cryptoWorkerInterface.js";
-
-export { InternalWalletState } from "./internal-wallet-state.js";
-export * from "./wallet-api-types.js";
-export * from "./wallet.js";
-
-export * from "./backup/index.js";
-
-export * from "./exchanges.js";
-
-export * from "./refresh.js";
-export * from "./withdraw.js";
-
-export * from "./dbless.js";
-
-export * from "./crypto/cryptoImplementation.js";
-export * from "./crypto/cryptoTypes.js";
-
-export * from "./util/denominations.js";
-export * from "./util/timer.js";
-
export { SynchronousCryptoWorkerFactoryPlain } from "./crypto/workers/synchronousWorkerFactoryPlain.js";
+export * from "./dbless.js";
export * from "./host-common.js";
export * from "./host.js";
+export * from "./versions.js";
+export * from "./wallet-api-types.js";
+export * from "./wallet.js";
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index 325bc24a8..15de0571c 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -114,21 +114,18 @@ import {
DenominationRecord,
PurchaseRecord,
PurchaseStatus,
- RefundReason,
- WalletStoresV1,
-} from "./db.js";
-import {
- getCandidateWithdrawalDenomsTx,
RefundGroupRecord,
RefundGroupStatus,
RefundItemRecord,
RefundItemStatus,
+ RefundReason,
timestampPreciseToDb,
timestampProtocolFromDb,
timestampProtocolToDb,
WalletDbReadOnlyTransaction,
WalletDbReadWriteTransaction,
-} from "./index.js";
+ WalletStoresV1,
+} from "./db.js";
import {
EXCHANGE_COINS_LOCK,
InternalWalletState,
@@ -147,6 +144,7 @@ import {
import { assertUnreachable } from "./util/assertUnreachable.js";
import { PreviousPayCoins, selectPayCoinsNew } from "./util/coinSelection.js";
import { checkDbInvariant } from "./util/invariants.js";
+import { getCandidateWithdrawalDenomsTx } from "./withdraw.js";
/**
* Logger.
diff --git a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
index 03bc5a4b9..d862a3b3a 100644
--- a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
@@ -66,11 +66,11 @@ import {
PeerPullPaymentCreditStatus,
WithdrawalGroupStatus,
WithdrawalRecordType,
- fetchFreshExchange,
timestampOptionalPreciseFromDb,
timestampPreciseFromDb,
timestampPreciseToDb,
-} from "./index.js";
+} from "./db.js";
+import { fetchFreshExchange } from "./exchanges.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import {
codecForExchangePurseStatus,
diff --git a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts
index 1d6cb3d18..0b4f49ce2 100644
--- a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts
@@ -74,21 +74,20 @@ import {
spendCoins,
} from "./common.js";
import {
- DbReadWriteTransaction,
- InternalWalletState,
PeerPullDebitRecordStatus,
PeerPullPaymentIncomingRecord,
RefreshOperationStatus,
- StoreNames,
WalletStoresV1,
- createRefreshGroup,
timestampPreciseToDb,
-} from "./index.js";
+} from "./db.js";
+import { InternalWalletState } from "./internal-wallet-state.js";
import {
codecForExchangePurseStatus,
getTotalPeerPaymentCost,
queryCoinInfosForSelection,
} from "./pay-peer-common.js";
+import { DbReadWriteTransaction, StoreNames } from "./query.js";
+import { createRefreshGroup } from "./refresh.js";
import {
constructTransactionIdentifier,
notifyTransition,
diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts
index 0795b0c5c..ed1e09495 100644
--- a/packages/taler-wallet-core/src/pay-peer-push-credit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-push-credit.ts
@@ -60,9 +60,7 @@ import {
TransactionContext,
constructTaskIdentifier,
} from "./common.js";
-import { fetchFreshExchange } from "./exchanges.js";
import {
- InternalWalletState,
KycPendingInfo,
KycUserType,
PeerPushCreditStatus,
@@ -70,7 +68,9 @@ import {
WithdrawalGroupStatus,
WithdrawalRecordType,
timestampPreciseToDb,
-} from "./index.js";
+} from "./db.js";
+import { fetchFreshExchange } from "./exchanges.js";
+import { InternalWalletState } from "./internal-wallet-state.js";
import {
codecForExchangePurseStatus,
getMergeReserveInfo,
diff --git a/packages/taler-wallet-core/src/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/pay-peer-push-debit.ts
index ec1a37a31..355418601 100644
--- a/packages/taler-wallet-core/src/pay-peer-push-debit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-push-debit.ts
@@ -61,17 +61,17 @@ import {
PeerPushDebitRecord,
PeerPushDebitStatus,
RefreshOperationStatus,
- createRefreshGroup,
timestampPreciseToDb,
timestampProtocolFromDb,
timestampProtocolToDb,
-} from "./index.js";
+} from "./db.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import {
codecForExchangePurseStatus,
getTotalPeerPaymentCost,
queryCoinInfosForSelection,
} from "./pay-peer-common.js";
+import { createRefreshGroup } from "./refresh.js";
import {
constructTransactionIdentifier,
notifyTransition,
diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts
index f139208be..4c3bb493a 100644
--- a/packages/taler-wallet-core/src/refresh.ts
+++ b/packages/taler-wallet-core/src/refresh.ts
@@ -81,18 +81,15 @@ import {
CoinSourceType,
DenominationRecord,
RefreshCoinStatus,
+ RefreshGroupPerExchangeInfo,
RefreshGroupRecord,
RefreshOperationStatus,
-} from "./db.js";
-import { fetchFreshExchange } from "./exchanges.js";
-import {
- getCandidateWithdrawalDenomsTx,
- RefreshGroupPerExchangeInfo,
RefreshSessionRecord,
timestampPreciseToDb,
WalletDbReadOnlyTransaction,
WalletDbReadWriteTransaction,
-} from "./index.js";
+} from "./db.js";
+import { fetchFreshExchange } from "./exchanges.js";
import {
EXCHANGE_COINS_LOCK,
InternalWalletState,
@@ -104,6 +101,7 @@ import {
import { assertUnreachable } from "./util/assertUnreachable.js";
import { selectWithdrawalDenominations } from "./util/coinSelection.js";
import { checkDbInvariant } from "./util/invariants.js";
+import { getCandidateWithdrawalDenomsTx } from "./withdraw.js";
const logger = new Logger("refresh.ts");
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts
index 2352c844f..d6fc604e8 100644
--- a/packages/taler-wallet-core/src/shepherd.ts
+++ b/packages/taler-wallet-core/src/shepherd.ts
@@ -49,14 +49,14 @@ import {
parseTaskIdentifier,
} from "./common.js";
import { CryptoApiStoppedError } from "./crypto/workers/crypto-dispatcher.js";
-import { processDepositGroup } from "./deposits.js";
-import { updateExchangeFromUrlHandler } from "./exchanges.js";
import {
OPERATION_STATUS_ACTIVE_FIRST,
OPERATION_STATUS_ACTIVE_LAST,
WalletDbAllStoresReadOnlyTransaction,
timestampAbsoluteFromDb,
-} from "./index.js";
+} from "./db.js";
+import { processDepositGroup } from "./deposits.js";
+import { updateExchangeFromUrlHandler } from "./exchanges.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import { processPurchase } from "./pay-merchant.js";
import { processPeerPullCredit } from "./pay-peer-pull-credit.js";
diff --git a/packages/taler-wallet-core/src/testing.ts b/packages/taler-wallet-core/src/testing.ts
index 38b2471e3..8192bacfd 100644
--- a/packages/taler-wallet-core/src/testing.ts
+++ b/packages/taler-wallet-core/src/testing.ts
@@ -56,12 +56,10 @@ import {
HttpRequestLibrary,
readSuccessResponseJsonOrThrow,
} from "@gnu-taler/taler-util/http";
-import { getRefreshesForTransaction } from "./index.js";
-import { InternalWalletState } from "./internal-wallet-state.js";
-import { checkLogicInvariant } from "./util/invariants.js";
import { getBalances } from "./balance.js";
import { createDepositGroup } from "./deposits.js";
import { fetchFreshExchange } from "./exchanges.js";
+import { InternalWalletState } from "./internal-wallet-state.js";
import {
confirmPay,
preparePayForUri,
@@ -77,7 +75,9 @@ import {
preparePeerPushCredit,
} from "./pay-peer-push-credit.js";
import { initiatePeerPushDebit } from "./pay-peer-push-debit.js";
+import { getRefreshesForTransaction } from "./refresh.js";
import { getTransactionById, getTransactions } from "./transactions.js";
+import { checkLogicInvariant } from "./util/invariants.js";
import { acceptWithdrawalFromUri } from "./withdraw.js";
const logger = new Logger("operations/testing.ts");
diff --git a/packages/taler-wallet-core/src/transactions.ts b/packages/taler-wallet-core/src/transactions.ts
index 8c6c3f5aa..2050abac2 100644
--- a/packages/taler-wallet-core/src/transactions.ts
+++ b/packages/taler-wallet-core/src/transactions.ts
@@ -58,12 +58,15 @@ import {
import {
DepositElementStatus,
DepositGroupRecord,
+ OPERATION_STATUS_ACTIVE_FIRST,
+ OPERATION_STATUS_ACTIVE_LAST,
OperationRetryRecord,
PeerPullCreditRecord,
PeerPullDebitRecordStatus,
PeerPullPaymentIncomingRecord,
PeerPushCreditStatus,
PeerPushDebitRecord,
+ PeerPushDebitStatus,
PeerPushPaymentIncomingRecord,
PurchaseRecord,
PurchaseStatus,
@@ -71,6 +74,9 @@ import {
RefreshOperationStatus,
RefundGroupRecord,
RewardRecord,
+ timestampPreciseFromDb,
+ timestampProtocolFromDb,
+ WalletDbReadOnlyTransaction,
WithdrawalGroupRecord,
WithdrawalGroupStatus,
WithdrawalRecordType,
@@ -84,14 +90,6 @@ import {
ExchangeWireDetails,
getExchangeWireDetailsInTx,
} from "./exchanges.js";
-import {
- OPERATION_STATUS_ACTIVE_FIRST,
- OPERATION_STATUS_ACTIVE_LAST,
- PeerPushDebitStatus,
- timestampPreciseFromDb,
- timestampProtocolFromDb,
- WalletDbReadOnlyTransaction,
-} from "./index.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import {
computePayMerchantTransactionActions,
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts
index f33891c88..88dd08f63 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -54,18 +54,15 @@ import {
TalerProtocolTimestamp,
UnblindedSignature,
} from "@gnu-taler/taler-util";
-import { DenominationRecord } from "../db.js";
-import {
- getExchangeWireDetailsInTx,
- isWithdrawableDenom,
- WalletDbReadOnlyTransaction,
-} from "../index.js";
-import { InternalWalletState } from "../internal-wallet-state.js";
import {
getMerchantPaymentBalanceDetails,
getPeerPaymentBalanceDetailsInTx,
} from "../balance.js";
import { getAutoRefreshExecuteThreshold } from "../common.js";
+import { DenominationRecord, WalletDbReadOnlyTransaction } from "../db.js";
+import { getExchangeWireDetailsInTx } from "../exchanges.js";
+import { InternalWalletState } from "../internal-wallet-state.js";
+import { isWithdrawableDenom } from "./denominations.js";
import { checkDbInvariant, checkLogicInvariant } from "./invariants.js";
const logger = new Logger("coinSelection.ts");
diff --git a/packages/taler-wallet-core/src/util/denominations.ts b/packages/taler-wallet-core/src/util/denominations.ts
index db6e69956..9557c078a 100644
--- a/packages/taler-wallet-core/src/util/denominations.ts
+++ b/packages/taler-wallet-core/src/util/denominations.ts
@@ -27,8 +27,7 @@ import {
TalerProtocolTimestamp,
TimePoint,
} from "@gnu-taler/taler-util";
-import { DenominationRecord } from "../db.js";
-import { timestampProtocolFromDb } from "../index.js";
+import { DenominationRecord, timestampProtocolFromDb } from "../db.js";
/**
* Given a list of denominations with the same value and same period of time:
diff --git a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts
index c4a2f2d5c..f01dc4e21 100644
--- a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts
+++ b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts
@@ -30,12 +30,9 @@ import {
parsePaytoUri,
strcmp,
} from "@gnu-taler/taler-util";
-import {
- DenominationRecord,
- InternalWalletState,
- getExchangeWireDetailsInTx,
- timestampProtocolFromDb,
-} from "../index.js";
+import { DenominationRecord, timestampProtocolFromDb } from "../db.js";
+import { getExchangeWireDetailsInTx } from "../exchanges.js";
+import { InternalWalletState } from "../internal-wallet-state.js";
import { CoinInfo } from "./coinSelection.js";
import { checkDbInvariant } from "./invariants.js";
diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts
index 7e9b295bd..4979b2623 100644
--- a/packages/taler-wallet-core/src/withdraw.ts
+++ b/packages/taler-wallet-core/src/withdraw.ts
@@ -15,6 +15,11 @@
*/
/**
+ * @fileoverview Implementation of Taler withdrawals, both
+ * bank-integrated and manual.
+ */
+
+/**
* Imports.
*/
import {
@@ -26,6 +31,7 @@ import {
AmountLike,
AmountString,
Amounts,
+ AsyncFlag,
BankWithdrawDetails,
CancellationToken,
CoinStatus,
@@ -105,11 +111,14 @@ import {
KycPendingInfo,
PlanchetRecord,
PlanchetStatus,
+ WalletDbReadOnlyTransaction,
+ WalletDbReadWriteTransaction,
WalletStoresV1,
WgInfo,
WithdrawalGroupRecord,
WithdrawalGroupStatus,
WithdrawalRecordType,
+ timestampPreciseToDb,
} from "./db.js";
import {
ReadyExchangeSummary,
@@ -119,12 +128,6 @@ import {
listExchanges,
markExchangeUsed,
} from "./exchanges.js";
-import {
- WalletDbReadOnlyTransaction,
- WalletDbReadWriteTransaction,
- isWithdrawableDenom,
- timestampPreciseToDb,
-} from "./index.js";
import { InternalWalletState } from "./internal-wallet-state.js";
import { DbAccess } from "./query.js";
import {
@@ -137,6 +140,7 @@ import {
selectForcedWithdrawalDenominations,
selectWithdrawalDenominations,
} from "./util/coinSelection.js";
+import { isWithdrawableDenom } from "./util/denominations.js";
import { checkDbInvariant, checkLogicInvariant } from "./util/invariants.js";
import {
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
@@ -628,7 +632,7 @@ export async function getCandidateWithdrawalDenomsTx(
exchangeBaseUrl: string,
currency: string,
): Promise<DenominationRecord[]> {
- // FIXME: Use denom groups instead of querying all denominations!
+ // FIXME(https://bugs.taler.net/n/8446): Use denom groups instead of querying all denominations!
const allDenoms =
await tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl);
return allDenoms
@@ -730,10 +734,11 @@ interface WithdrawalBatchResult {
batchResp: ExchangeWithdrawBatchResponse;
}
-enum AmlStatus {
- normal = 0,
- pending = 1,
- fronzen = 2,
+// FIXME: Move to exchange API types
+enum ExchangeAmlStatus {
+ Normal = 0,
+ Pending = 1,
+ Frozen = 2,
}
/**
@@ -818,7 +823,7 @@ async function handleKycRequired(
method: "GET",
});
let kycUrl: string;
- let amlStatus: AmlStatus | undefined;
+ let amlStatus: ExchangeAmlStatus | undefined;
if (
kycStatusRes.status === HttpStatusCode.Ok ||
// FIXME: NoContent is not expected https://docs.taler.net/core/api-exchange.html#post--purses-$PURSE_PUB-merge
@@ -872,11 +877,11 @@ async function handleKycRequired(
};
wg2.kycUrl = kycUrl;
wg2.status =
- amlStatus === AmlStatus.normal || amlStatus === undefined
+ amlStatus === ExchangeAmlStatus.Normal || amlStatus === undefined
? WithdrawalGroupStatus.PendingKyc
- : amlStatus === AmlStatus.pending
+ : amlStatus === ExchangeAmlStatus.Pending
? WithdrawalGroupStatus.PendingAml
- : amlStatus === AmlStatus.fronzen
+ : amlStatus === ExchangeAmlStatus.Frozen
? WithdrawalGroupStatus.SuspendedAml
: assertUnreachable(amlStatus);
@@ -1333,7 +1338,7 @@ async function queryReserve(
*
* Used to store some cached info during a withdrawal operation.
*/
-export interface WithdrawalGroupContext {
+interface WithdrawalGroupContext {
numPlanchets: number;
planchetsFinished: Set<string>;
@@ -1659,19 +1664,11 @@ export async function processWithdrawalGroup(
switch (withdrawalGroup.status) {
case WithdrawalGroupStatus.PendingRegisteringBank:
- await processReserveBankStatus(ws, withdrawalGroupId);
- // FIXME: This will get called by the main task loop, why call it here?!
- return await processWithdrawalGroup(
- ws,
- withdrawalGroupId,
- cancellationToken,
- );
- case WithdrawalGroupStatus.PendingQueryingStatus: {
+ return await processReserveBankStatus(ws, withdrawalGroupId);
+ case WithdrawalGroupStatus.PendingQueryingStatus:
return queryReserve(ws, withdrawalGroupId, cancellationToken);
- }
- case WithdrawalGroupStatus.PendingWaitConfirmBank: {
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
return await processReserveBankStatus(ws, withdrawalGroupId);
- }
case WithdrawalGroupStatus.PendingAml:
// FIXME: Handle this case, withdrawal doesn't support AML yet.
return TaskRunResult.backoff();
@@ -1768,29 +1765,34 @@ export async function getExchangeWithdrawalInfo(
logger.trace("computing earliest deposit expiration");
let earliestDepositExpiration: TalerProtocolTimestamp | undefined;
- for (let i = 0; i < selectedDenoms.selectedDenoms.length; i++) {
- const ds = selectedDenoms.selectedDenoms[i];
- // FIXME: Do in one transaction!
- const denom = await ws.db.runReadOnlyTx(["denominations"], async (tx) => {
- return ws.getDenomInfo(ws, tx, exchangeBaseUrl, ds.denomPubHash);
- });
- checkDbInvariant(!!denom);
- hasDenomWithAgeRestriction =
- hasDenomWithAgeRestriction || denom.denomPub.age_mask > 0;
- const expireDeposit = denom.stampExpireDeposit;
- if (!earliestDepositExpiration) {
- earliestDepositExpiration = expireDeposit;
- continue;
- }
- if (
- AbsoluteTime.cmp(
- AbsoluteTime.fromProtocolTimestamp(expireDeposit),
- AbsoluteTime.fromProtocolTimestamp(earliestDepositExpiration),
- ) < 0
- ) {
- earliestDepositExpiration = expireDeposit;
+
+ await ws.db.runReadOnlyTx(["denominations"], async (tx) => {
+ for (let i = 0; i < selectedDenoms.selectedDenoms.length; i++) {
+ const ds = selectedDenoms.selectedDenoms[i];
+ const denom = await ws.getDenomInfo(
+ ws,
+ tx,
+ exchangeBaseUrl,
+ ds.denomPubHash,
+ );
+ checkDbInvariant(!!denom);
+ hasDenomWithAgeRestriction =
+ hasDenomWithAgeRestriction || denom.denomPub.age_mask > 0;
+ const expireDeposit = denom.stampExpireDeposit;
+ if (!earliestDepositExpiration) {
+ earliestDepositExpiration = expireDeposit;
+ continue;
+ }
+ if (
+ AbsoluteTime.cmp(
+ AbsoluteTime.fromProtocolTimestamp(expireDeposit),
+ AbsoluteTime.fromProtocolTimestamp(earliestDepositExpiration),
+ ) < 0
+ ) {
+ earliestDepositExpiration = expireDeposit;
+ }
}
- }
+ });
checkLogicInvariant(!!earliestDepositExpiration);
@@ -2192,13 +2194,7 @@ async function processReserveBankStatus(
// Bank still needs to know our reserve info
if (!status.selection_done) {
await registerReserveWithBank(ws, withdrawalGroupId);
- return await processReserveBankStatus(ws, withdrawalGroupId);
- }
-
- // FIXME: Why do we do this?!
- if (withdrawalGroup.status === WithdrawalGroupStatus.PendingRegisteringBank) {
- await registerReserveWithBank(ws, withdrawalGroupId);
- return await processReserveBankStatus(ws, withdrawalGroupId);
+ return TaskRunResult.progress();
}
const transitionInfo = await ws.db.runReadWriteTx(
@@ -2479,6 +2475,14 @@ export async function internalCreateWithdrawalGroup(
return res.withdrawalGroup;
}
+/**
+ * Accept a bank-integrated withdrawal.
+ *
+ * Before returning, the wallet tries to register the reserve with the bank.
+ *
+ * Thus after this call returns, the withdrawal operation can be confirmed
+ * with the bank.
+ */
export async function acceptWithdrawalFromUri(
ws: InternalWalletState,
req: {
@@ -2560,11 +2564,10 @@ export async function acceptWithdrawalFromUri(
const ctx = new WithdrawTransactionContext(ws, withdrawalGroupId);
- const transactionId = ctx.transactionId;
+ // FIXME: Do we wait here until the reserve is registered with the bank?
+
+ await waitWithdrawalRegistered(ws, ctx);
- // We do this here, as the reserve should be registered before we return,
- // so that we can redirect the user to the bank's status page.
- await processReserveBankStatus(ws, withdrawalGroupId);
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
withdrawalGroupId,
});
@@ -2582,10 +2585,93 @@ export async function acceptWithdrawalFromUri(
return {
reservePub: withdrawalGroup.reservePub,
confirmTransferUrl: withdrawInfo.confirmTransferUrl,
- transactionId,
+ transactionId: ctx.transactionId,
};
}
+async function internalWaitWithdrawalRegistered(
+ ws: InternalWalletState,
+ ctx: WithdrawTransactionContext,
+ withdrawalNotifFlag: AsyncFlag,
+): Promise<void> {
+ while (true) {
+ const { withdrawalRec, retryRec } = await ws.db.runReadOnlyTx(
+ ["withdrawalGroups", "operationRetries"],
+ async (tx) => {
+ return {
+ withdrawalRec: await tx.withdrawalGroups.get(ctx.withdrawalGroupId),
+ retryRec: await tx.operationRetries.get(ctx.taskId),
+ };
+ },
+ );
+
+ if (!withdrawalRec) {
+ throw Error("withdrawal not found anymore");
+ }
+
+ switch (withdrawalRec.status) {
+ case WithdrawalGroupStatus.FailedBankAborted:
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
+ {},
+ );
+ case WithdrawalGroupStatus.PendingKyc:
+ case WithdrawalGroupStatus.PendingAml:
+ case WithdrawalGroupStatus.PendingQueryingStatus:
+ case WithdrawalGroupStatus.PendingReady:
+ case WithdrawalGroupStatus.Done:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
+ return;
+ case WithdrawalGroupStatus.PendingRegisteringBank:
+ break;
+ default: {
+ if (retryRec) {
+ if (retryRec.lastError) {
+ throw TalerError.fromUncheckedDetail(retryRec.lastError);
+ } else {
+ throw Error("withdrawal unexpectedly pending");
+ }
+ }
+ }
+ }
+
+ await withdrawalNotifFlag.wait();
+ withdrawalNotifFlag.reset();
+ }
+}
+
+async function waitWithdrawalRegistered(
+ ws: InternalWalletState,
+ ctx: WithdrawTransactionContext,
+): Promise<void> {
+ // FIXME: We should use Symbol.dispose magic here for cleanup!
+
+ const withdrawalNotifFlag = new AsyncFlag();
+ // Raise exchangeNotifFlag whenever we get a notification
+ // about our exchange.
+ const cancelNotif = ws.addNotificationListener((notif) => {
+ if (
+ notif.type === NotificationType.TransactionStateTransition &&
+ notif.transactionId === ctx.transactionId
+ ) {
+ logger.info(`raising update notification: ${j2s(notif)}`);
+ withdrawalNotifFlag.raise();
+ }
+ });
+
+ try {
+ const res = await internalWaitWithdrawalRegistered(
+ ws,
+ ctx,
+ withdrawalNotifFlag,
+ );
+ logger.info("done waiting for ready exchange");
+ return res;
+ } finally {
+ cancelNotif();
+ }
+}
+
async function fetchAccount(
ws: InternalWalletState,
instructedAmount: AmountJson,
@@ -2669,7 +2755,7 @@ async function fetchWithdrawalAccountInfo(
reservePub?: string;
},
): Promise<WithdrawalExchangeAccountDetails[]> {
- const { exchange, instructedAmount } = req;
+ const { exchange } = req;
const withdrawalAccounts: WithdrawalExchangeAccountDetails[] = [];
for (let acct of exchange.wireInfo.accounts) {
const acctInfo = await fetchAccount(
@@ -2732,10 +2818,10 @@ export async function createManualWithdrawal(
reserveKeyPair,
});
- const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
- const ctx = new WithdrawTransactionContext(ws, withdrawalGroupId);
-
- const transactionId = ctx.transactionId;
+ const ctx = new WithdrawTransactionContext(
+ ws,
+ withdrawalGroup.withdrawalGroupId,
+ );
const exchangePaytoUris = await ws.db.runReadOnlyTx(
["withdrawalGroups", "exchanges", "exchangeDetails"],
@@ -2750,6 +2836,6 @@ export async function createManualWithdrawal(
reservePub: withdrawalGroup.reservePub,
exchangePaytoUris: exchangePaytoUris,
withdrawalAccountsList: withdrawalAccountsList,
- transactionId,
+ transactionId: ctx.transactionId,
};
}