summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-05-18 14:41:51 -0300
committerSebastian <sebasjm@gmail.com>2022-05-18 14:41:51 -0300
commitc67d0bff1daa35d380d1d71b94428a5026b56450 (patch)
treeb4e1f164e1bed3b13fa4ff5969806d2212079f41 /packages
parentd3a857743dd9ed2f7350bb64af8808729156edba (diff)
downloadwallet-core-c67d0bff1daa35d380d1d71b94428a5026b56450.tar.gz
wallet-core-c67d0bff1daa35d380d1d71b94428a5026b56450.tar.bz2
wallet-core-c67d0bff1daa35d380d1d71b94428a5026b56450.zip
all retryInfo function in the same namespace, adding missing retryInfo increment
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-wallet-core/src/bank-api-client.ts5
-rw-r--r--packages/taler-wallet-core/src/operations/backup/import.ts68
-rw-r--r--packages/taler-wallet-core/src/operations/backup/index.ts73
-rw-r--r--packages/taler-wallet-core/src/operations/deposits.ts6
-rw-r--r--packages/taler-wallet-core/src/operations/exchanges.ts9
-rw-r--r--packages/taler-wallet-core/src/operations/pay.ts22
-rw-r--r--packages/taler-wallet-core/src/operations/recoup.ts36
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts90
-rw-r--r--packages/taler-wallet-core/src/operations/refund.ts40
-rw-r--r--packages/taler-wallet-core/src/operations/reserves.ts23
-rw-r--r--packages/taler-wallet-core/src/operations/tip.ts53
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts15
-rw-r--r--packages/taler-wallet-core/src/util/retries.ts61
-rw-r--r--packages/taler-wallet-core/src/wallet.ts7
14 files changed, 205 insertions, 303 deletions
diff --git a/packages/taler-wallet-core/src/bank-api-client.ts b/packages/taler-wallet-core/src/bank-api-client.ts
index 14bf07174..fb859ece3 100644
--- a/packages/taler-wallet-core/src/bank-api-client.ts
+++ b/packages/taler-wallet-core/src/bank-api-client.ts
@@ -120,7 +120,10 @@ export namespace BankApi {
if (respJson.paytoUri) {
paytoUri = respJson.paytoUri;
}
- } catch (e) {}
+ } catch (e) {
+ logger.error("error trying to parse json from response", e);
+ throw TalerError.fromException(e);
+ }
return {
password,
username,
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts
index a0a603ca3..16a88fe7c 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -15,54 +15,30 @@
*/
import {
- BackupPurchase,
AmountJson,
- Amounts,
- BackupDenomSel,
- WalletBackupContentV1,
- BackupCoinSourceType,
- BackupProposalStatus,
- codecForContractTerms,
- BackupRefundState,
- RefreshReason,
- BackupRefreshReason,
- DenomKeyType,
- AbsoluteTime,
- TalerProtocolTimestamp,
+ Amounts, BackupCoinSourceType, BackupDenomSel, BackupProposalStatus,
+ BackupPurchase, BackupRefreshReason, BackupRefundState, codecForContractTerms,
+ DenomKeyType, j2s, Logger, RefreshReason, TalerProtocolTimestamp,
+ WalletBackupContentV1
} from "@gnu-taler/taler-util";
import {
- WalletContractData,
- DenomSelectionState,
- DenominationVerificationStatus,
- CoinSource,
+ AbortStatus, CoinSource,
CoinSourceType,
- CoinStatus,
- ReserveBankInfo,
- ReserveRecordStatus,
- ProposalDownload,
- ProposalStatus,
- WalletRefundItem,
- RefundState,
- AbortStatus,
- RefreshSessionRecord,
- WireInfo,
- WalletStoresV1,
- RefreshCoinStatus,
- OperationStatus,
+ CoinStatus, DenominationVerificationStatus, DenomSelectionState, OperationStatus, ProposalDownload,
+ ProposalStatus, RefreshCoinStatus, RefreshSessionRecord, RefundState, ReserveBankInfo,
+ ReserveRecordStatus, WalletContractData, WalletRefundItem, WalletStoresV1, WireInfo
} from "../../db.js";
+import { InternalWalletState } from "../../internal-wallet-state.js";
import { PayCoinSelection } from "../../util/coinSelection.js";
-import { j2s } from "@gnu-taler/taler-util";
import {
checkDbInvariant,
- checkLogicInvariant,
+ checkLogicInvariant
} from "../../util/invariants.js";
-import { Logger } from "@gnu-taler/taler-util";
-import { resetRetryInfo } from "../../util/retries.js";
-import { InternalWalletState } from "../../internal-wallet-state.js";
-import { provideBackupState } from "./state.js";
-import { makeEventId, TombstoneTag } from "../transactions.js";
-import { getExchangeDetails } from "../exchanges.js";
import { GetReadOnlyAccess, GetReadWriteAccess } from "../../util/query.js";
+import { RetryInfo } from "../../util/retries.js";
+import { getExchangeDetails } from "../exchanges.js";
+import { makeEventId, TombstoneTag } from "../transactions.js";
+import { provideBackupState } from "./state.js";
const logger = new Logger("operations/backup/import.ts");
@@ -276,7 +252,7 @@ export async function importBackup(
protocolVersionRange: backupExchange.protocol_version_range,
},
permanent: true,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastUpdate: undefined,
nextUpdate: TalerProtocolTimestamp.now(),
nextRefreshCheck: TalerProtocolTimestamp.now(),
@@ -464,7 +440,7 @@ export async function importBackup(
timestampReserveInfoPosted:
backupReserve.bank_info?.timestamp_reserve_info_posted,
senderWire: backupReserve.sender_wire,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: undefined,
initialWithdrawalGroupId:
backupReserve.initial_withdrawal_group_id,
@@ -505,7 +481,7 @@ export async function importBackup(
backupWg.raw_withdrawal_amount,
),
reservePub,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
secretSeed: backupWg.secret_seed,
timestampStart: backupWg.timestamp_created,
timestampFinish: backupWg.timestamp_finish,
@@ -618,7 +594,7 @@ export async function importBackup(
cryptoComp.proposalNoncePrivToPub[backupProposal.nonce_priv],
proposalId: backupProposal.proposal_id,
repurchaseProposalId: backupProposal.repurchase_proposal_id,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
download,
proposalStatus,
});
@@ -753,7 +729,7 @@ export async function importBackup(
cryptoComp.proposalNoncePrivToPub[backupPurchase.nonce_priv],
lastPayError: undefined,
autoRefundDeadline: TalerProtocolTimestamp.never(),
- refundStatusRetryInfo: resetRetryInfo(),
+ refundStatusRetryInfo: RetryInfo.reset(),
lastRefundStatusError: undefined,
refundAwaiting: undefined,
timestampAccept: backupPurchase.timestamp_accept,
@@ -764,7 +740,7 @@ export async function importBackup(
lastSessionId: undefined,
abortStatus,
// FIXME!
- payRetryInfo: resetRetryInfo(),
+ payRetryInfo: RetryInfo.reset(),
download,
paymentSubmitPending:
!backupPurchase.timestamp_first_successful_pay,
@@ -865,7 +841,7 @@ export async function importBackup(
Amounts.parseOrThrow(x.estimated_output_amount),
),
refreshSessionPerCoin,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
});
}
}
@@ -891,7 +867,7 @@ export async function importBackup(
merchantBaseUrl: backupTip.exchange_base_url,
merchantTipId: backupTip.merchant_tip_id,
pickedUpTimestamp: backupTip.timestamp_finished,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
secretSeed: backupTip.secret_seed,
tipAmountEffective: denomsSel.totalCoinValue,
tipAmountRaw: Amounts.parseOrThrow(backupTip.tip_amount_raw),
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts
index 0b2bd7b80..69ba1ddbc 100644
--- a/packages/taler-wallet-core/src/operations/backup/index.ts
+++ b/packages/taler-wallet-core/src/operations/backup/index.ts
@@ -25,10 +25,9 @@
* Imports.
*/
import {
- AmountString,
+ AbsoluteTime, AmountString,
BackupRecovery,
- buildCodecForObject,
- canonicalizeBaseUrl,
+ buildCodecForObject, bytesToString, canonicalizeBaseUrl,
canonicalJson,
Codec,
codecForAmountString,
@@ -37,39 +36,22 @@ import {
codecForNumber,
codecForString,
codecOptional,
- ConfirmPayResultType,
- DenomKeyType,
- durationFromSpec,
- hashDenomPub,
+ ConfirmPayResultType, decodeCrock, DenomKeyType,
+ durationFromSpec, eddsaGetPublic,
+ EddsaKeyPair,
+ encodeCrock,
+ getRandomBytes,
+ hash, hashDenomPub,
HttpStatusCode,
- j2s,
- Logger,
+ j2s, kdf, Logger,
notEmpty,
PreparePayResultType,
RecoveryLoadRequest,
- RecoveryMergeStrategy,
- TalerErrorDetail,
- AbsoluteTime,
- URL,
- WalletBackupContentV1,
- TalerProtocolTimestamp,
+ RecoveryMergeStrategy, rsaBlind, secretbox, secretbox_open, stringToBytes, TalerErrorDetail, TalerProtocolTimestamp, URL,
+ WalletBackupContentV1
} from "@gnu-taler/taler-util";
import { gunzipSync, gzipSync } from "fflate";
-import { InternalWalletState } from "../../internal-wallet-state.js";
-import { kdf } from "@gnu-taler/taler-util";
-import { secretbox, secretbox_open } from "@gnu-taler/taler-util";
-import {
- bytesToString,
- decodeCrock,
- eddsaGetPublic,
- EddsaKeyPair,
- encodeCrock,
- getRandomBytes,
- hash,
- rsaBlind,
- stringToBytes,
-} from "@gnu-taler/taler-util";
-import { CryptoDispatcher } from "../../crypto/workers/cryptoDispatcher.js";
+import { TalerCryptoInterface } from "../../crypto/cryptoImplementation.js";
import {
BackupProviderRecord,
BackupProviderState,
@@ -78,28 +60,28 @@ import {
ConfigRecord,
WalletBackupConfState,
WalletStoresV1,
- WALLET_BACKUP_STATE_KEY,
+ WALLET_BACKUP_STATE_KEY
} from "../../db.js";
+import { InternalWalletState } from "../../internal-wallet-state.js";
import {
readSuccessResponseJsonOrThrow,
- readTalerErrorResponse,
+ readTalerErrorResponse
} from "../../util/http.js";
import {
checkDbInvariant,
- checkLogicInvariant,
+ checkLogicInvariant
} from "../../util/invariants.js";
import { GetReadWriteAccess } from "../../util/query.js";
-import { resetRetryInfo, updateRetryInfoTimeout } from "../../util/retries.js";
+import { RetryInfo } from "../../util/retries.js";
+import { guardOperationException } from "../common.js";
import {
checkPaymentByProposalId,
confirmPay,
- preparePayForUri,
+ preparePayForUri
} from "../pay.js";
import { exportBackup } from "./export.js";
import { BackupCryptoPrecomputedData, importBackup } from "./import.js";
import { getWalletBackupState, provideBackupState } from "./state.js";
-import { guardOperationException } from "../common.js";
-import { TalerCryptoInterface } from "../../crypto/cryptoImplementation.js";
const logger = new Logger("operations/backup.ts");
@@ -309,8 +291,8 @@ async function runBackupCycleForProvider(
"if-none-match": newHash,
...(provider.lastBackupHash
? {
- "if-match": provider.lastBackupHash,
- }
+ "if-match": provider.lastBackupHash,
+ }
: {}),
},
});
@@ -344,7 +326,7 @@ async function runBackupCycleForProvider(
}
const res = await preparePayForUri(ws, talerUri);
let proposalId = res.proposalId;
- let doPay: boolean = false;
+ let doPay = false;
switch (res.status) {
case PreparePayResultType.InsufficientBalance:
// FIXME: record in provider state!
@@ -434,7 +416,7 @@ async function runBackupCycleForProvider(
// FIXME: Allocate error code for this situation?
prov.state = {
tag: BackupProviderStateTag.Retrying,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
};
await tx.backupProvider.put(prov);
});
@@ -472,13 +454,12 @@ async function incrementBackupRetryInTx(
return;
}
if (pr.state.tag === BackupProviderStateTag.Retrying) {
- pr.state.retryInfo.retryCounter++;
pr.state.lastError = err;
- updateRetryInfoTimeout(pr.state.retryInfo);
+ pr.state.retryInfo = RetryInfo.increment(pr.state.retryInfo);
} else if (pr.state.tag === BackupProviderStateTag.Ready) {
pr.state = {
tag: BackupProviderStateTag.Retrying,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: err,
};
}
@@ -685,7 +666,9 @@ export async function addBackupProvider(
});
}
-export async function restoreFromRecoverySecret(): Promise<void> {}
+export async function restoreFromRecoverySecret(): Promise<void> {
+ return;
+}
/**
* Information about one provider.
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts
index 2f5f9aa15..27460849a 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -47,7 +47,7 @@ import { DepositGroupRecord, OperationStatus, WireFee } from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { PayCoinSelection, selectPayCoins } from "../util/coinSelection.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
import { guardOperationException } from "./common.js";
import { getExchangeDetails } from "./exchanges.js";
import {
@@ -85,7 +85,7 @@ async function setupDepositGroupRetry(
return;
}
if (options.resetRetry) {
- x.retryInfo = resetRetryInfo();
+ x.retryInfo = RetryInfo.reset();
} else {
x.retryInfo = RetryInfo.increment(x.retryInfo);
}
@@ -599,7 +599,7 @@ export async function createDepositGroup(
payto_uri: req.depositPaytoUri,
salt: wireSalt,
},
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
operationStatus: OperationStatus.Pending,
lastError: undefined,
};
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts
index 72cbdc15b..b10505b27 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -63,7 +63,7 @@ import {
readSuccessResponseTextOrThrow,
} from "../util/http.js";
import { DbAccess, GetReadOnlyAccess } from "../util/query.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
import {
WALLET_CACHE_BREAKER_CLIENT_VERSION,
WALLET_EXCHANGE_PROTOCOL_VERSION,
@@ -116,6 +116,9 @@ async function reportExchangeUpdateError(
if (!exchange) {
return;
}
+ if (!exchange.retryInfo) {
+ logger.reportBreak();
+ }
exchange.lastError = err;
await tx.exchanges.put(exchange);
});
@@ -137,7 +140,7 @@ async function setupExchangeUpdateRetry(
return;
}
if (options.reset) {
- exchange.retryInfo = resetRetryInfo();
+ exchange.retryInfo = RetryInfo.reset();
} else {
exchange.retryInfo = RetryInfo.increment(exchange.retryInfo);
}
@@ -399,7 +402,7 @@ async function provideExchangeRecord(
const r: ExchangeRecord = {
permanent: true,
baseUrl: baseUrl,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
detailsPointer: undefined,
lastUpdate: undefined,
nextUpdate: AbsoluteTime.toTimestamp(now),
diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts
index 325d07bd1..ceba7ef8c 100644
--- a/packages/taler-wallet-core/src/operations/pay.ts
+++ b/packages/taler-wallet-core/src/operations/pay.ts
@@ -97,10 +97,7 @@ import {
} from "../util/http.js";
import { GetReadWriteAccess } from "../util/query.js";
import {
- getRetryDuration,
- resetRetryInfo,
RetryInfo,
- updateRetryInfoTimeout,
} from "../util/retries.js";
import { getExchangeDetails } from "./exchanges.js";
import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
@@ -438,8 +435,8 @@ async function recordConfirmPay(
proposalId: proposal.proposalId,
lastPayError: undefined,
lastRefundStatusError: undefined,
- payRetryInfo: resetRetryInfo(),
- refundStatusRetryInfo: resetRetryInfo(),
+ payRetryInfo: RetryInfo.reset(),
+ refundStatusRetryInfo: RetryInfo.reset(),
refundQueryRequested: false,
timestampFirstSuccessfulPay: undefined,
autoRefundDeadline: undefined,
@@ -494,6 +491,7 @@ async function reportProposalError(
logger.error(
`Asked to report an error for a proposal (${proposalId}) that is not active (no retryInfo)`,
);
+ logger.reportBreak();
return;
}
pr.lastError = err;
@@ -517,7 +515,7 @@ async function setupProposalRetry(
return;
}
if (options.reset) {
- pr.retryInfo = resetRetryInfo();
+ pr.retryInfo = RetryInfo.reset();
} else {
pr.retryInfo = RetryInfo.increment(pr.retryInfo);
}
@@ -541,7 +539,7 @@ async function setupPurchasePayRetry(
return;
}
if (options.reset) {
- p.payRetryInfo = resetRetryInfo();
+ p.payRetryInfo = RetryInfo.reset();
} else {
p.payRetryInfo = RetryInfo.increment(p.payRetryInfo);
}
@@ -610,7 +608,7 @@ async function failProposalPermanently(
function getProposalRequestTimeout(proposal: ProposalRecord): Duration {
return durationMax(
{ d_ms: 60000 },
- durationMin({ d_ms: 5000 }, getRetryDuration(proposal.retryInfo)),
+ durationMin({ d_ms: 5000 }, RetryInfo.getDuration(proposal.retryInfo)),
);
}
@@ -938,7 +936,7 @@ async function startDownloadProposal(
proposalId: proposalId,
proposalStatus: ProposalStatus.Downloading,
repurchaseProposalId: undefined,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: undefined,
downloadSessionId: sessionId,
};
@@ -986,14 +984,14 @@ async function storeFirstPaySuccess(
purchase.paymentSubmitPending = false;
purchase.lastPayError = undefined;
purchase.lastSessionId = sessionId;
- purchase.payRetryInfo = resetRetryInfo();
+ purchase.payRetryInfo = RetryInfo.reset();
purchase.merchantPaySig = paySig;
const protoAr = purchase.download.contractData.autoRefund;
if (protoAr) {
const ar = Duration.fromTalerProtocolDuration(protoAr);
logger.info("auto_refund present");
purchase.refundQueryRequested = true;
- purchase.refundStatusRetryInfo = resetRetryInfo();
+ purchase.refundStatusRetryInfo = RetryInfo.reset();
purchase.lastRefundStatusError = undefined;
purchase.autoRefundDeadline = AbsoluteTime.toTimestamp(
AbsoluteTime.addDuration(AbsoluteTime.now(), ar),
@@ -1023,7 +1021,7 @@ async function storePayReplaySuccess(
}
purchase.paymentSubmitPending = false;
purchase.lastPayError = undefined;
- purchase.payRetryInfo = resetRetryInfo();
+ purchase.payRetryInfo = RetryInfo.reset();
purchase.lastSessionId = sessionId;
await tx.purchases.put(purchase);
});
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts
index 4fac2ec16..d36a10287 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -26,38 +26,28 @@
*/
import {
Amounts,
- codecForRecoupConfirmation,
- j2s,
- NotificationType,
+ codecForRecoupConfirmation, encodeCrock, getRandomBytes, j2s, Logger, NotificationType,
RefreshReason,
TalerErrorDetail,
- TalerProtocolTimestamp,
+ TalerProtocolTimestamp, URL
} from "@gnu-taler/taler-util";
-import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
import {
CoinRecord,
CoinSourceType,
- CoinStatus,
- RecoupGroupRecord,
+ CoinStatus, OperationStatus, RecoupGroupRecord,
RefreshCoinSource,
- ReserveRecordStatus,
- WithdrawCoinSource,
- WalletStoresV1,
- OperationStatus,
+ ReserveRecordStatus, WalletStoresV1, WithdrawCoinSource
} from "../db.js";
-
+import { InternalWalletState } from "../internal-wallet-state.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
-import { Logger, URL } from "@gnu-taler/taler-util";
+import { GetReadWriteAccess } from "../util/query.js";
import {
- resetRetryInfo,
- RetryInfo,
- updateRetryInfoTimeout,
+ RetryInfo
} from "../util/retries.js";
+import { guardOperationException } from "./common.js";
import { createRefreshGroup, processRefreshGroup } from "./refresh.js";
import { getReserveRequestTimeout, processReserve } from "./reserves.js";
-import { InternalWalletState } from "../internal-wallet-state.js";
-import { GetReadWriteAccess } from "../util/query.js";
-import { guardOperationException } from "./common.js";
+
const logger = new Logger("operations/recoup.ts");
@@ -78,7 +68,7 @@ async function setupRecoupRetry(
return;
}
if (options.reset) {
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
} else {
r.retryInfo = RetryInfo.increment(r.retryInfo);
}
@@ -139,7 +129,7 @@ async function putGroupAsFinished(
if (allFinished) {
logger.info("all recoups of recoup group are finished");
recoupGroup.timestampFinished = TalerProtocolTimestamp.now();
- recoupGroup.retryInfo = resetRetryInfo();
+ recoupGroup.retryInfo = RetryInfo.reset();
recoupGroup.lastError = undefined;
if (recoupGroup.scheduleRefreshCoins.length > 0) {
const refreshGroupId = await createRefreshGroup(
@@ -278,7 +268,7 @@ async function recoupWithdrawCoin(
const currency = updatedCoin.currentAmount.currency;
updatedCoin.currentAmount = Amounts.getZero(currency);
updatedReserve.reserveStatus = ReserveRecordStatus.QueryingStatus;
- updatedReserve.retryInfo = resetRetryInfo();
+ updatedReserve.retryInfo = RetryInfo.reset();
updatedReserve.operationStatus = OperationStatus.Pending;
await tx.coins.put(updatedCoin);
await tx.reserves.put(updatedReserve);
@@ -482,7 +472,7 @@ export async function createRecoupGroup(
lastError: undefined,
timestampFinished: undefined,
timestampStarted: TalerProtocolTimestamp.now(),
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
recoupFinishedPerCoin: coinPubs.map(() => false),
// Will be populated later
oldAmountPerCoin: [],
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts
index 215676118..ce8fd003a 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -15,20 +15,28 @@
*/
import {
- AgeCommitment,
- AgeRestriction,
- CoinPublicKeyString,
- DenomKeyType,
- encodeCrock,
+ AbsoluteTime, AgeCommitment,
+ AgeRestriction, AmountJson, Amounts, amountToPretty, codecForExchangeMeltResponse,
+ codecForExchangeRevealResponse,
+ CoinPublicKey, CoinPublicKeyString,
+ DenomKeyType, Duration,
+ durationFromSpec,
+ durationMul, encodeCrock,
ExchangeMeltRequest,
- ExchangeProtocolVersion,
- ExchangeRefreshRevealRequest,
- getRandomBytes,
+ ExchangeProtocolVersion, ExchangeRefreshRevealRequest, fnutil, getRandomBytes,
HashCodeString,
HttpStatusCode,
- j2s,
- TalerProtocolTimestamp,
+ j2s, Logger, NotificationType,
+ RefreshGroupId,
+ RefreshReason,
+ TalerErrorDetail, TalerProtocolTimestamp, URL
} from "@gnu-taler/taler-util";
+import { TalerCryptoInterface } from "../crypto/cryptoImplementation.js";
+import {
+ DerivedRefreshSession,
+ RefreshNewDenomInfo
+} from "../crypto/cryptoTypes.js";
+import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";
import {
CoinRecord,
CoinSourceType,
@@ -37,57 +45,29 @@ import {
OperationStatus,
RefreshCoinStatus,
RefreshGroupRecord,
- WalletStoresV1,
+ WalletStoresV1
} from "../db.js";
+import { TalerError } from "../errors.js";
import {
- codecForExchangeMeltResponse,
- codecForExchangeRevealResponse,
- CoinPublicKey,
- fnutil,
- NotificationType,
- RefreshGroupId,
- RefreshReason,
- TalerErrorDetail,
-} from "@gnu-taler/taler-util";
-import { AmountJson, Amounts } from "@gnu-taler/taler-util";
-import { amountToPretty } from "@gnu-taler/taler-util";
+ DenomInfo,
+ EXCHANGE_COINS_LOCK,
+ InternalWalletState
+} from "../internal-wallet-state.js";
import {
readSuccessResponseJsonOrThrow,
- readUnexpectedResponseDetails,
+ readUnexpectedResponseDetails
} from "../util/http.js";
import { checkDbInvariant } from "../util/invariants.js";
-import { Logger } from "@gnu-taler/taler-util";
+import { GetReadWriteAccess } from "../util/query.js";
import {
- resetRetryInfo,
- RetryInfo,
- updateRetryInfoTimeout,
+ RetryInfo
} from "../util/retries.js";
-import {
- Duration,
- durationFromSpec,
- durationMul,
- AbsoluteTime,
- URL,
-} from "@gnu-taler/taler-util";
+import { guardOperationException } from "./common.js";
import { updateExchangeFromUrl } from "./exchanges.js";
import {
- DenomInfo,
- EXCHANGE_COINS_LOCK,
- InternalWalletState,
-} from "../internal-wallet-state.js";
-import {
isWithdrawableDenom,
- selectWithdrawalDenominations,
+ selectWithdrawalDenominations
} from "./withdraw.js";
-import {
- DerivedRefreshSession,
- RefreshNewDenomInfo,
-} from "../crypto/cryptoTypes.js";
-import { GetReadWriteAccess } from "../util/query.js";
-import { guardOperationException } from "./common.js";
-import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";
-import { TalerCryptoInterface } from "../crypto/cryptoImplementation.js";
-import { TalerError } from "../errors.js";
const logger = new Logger("refresh.ts");
@@ -129,22 +109,22 @@ export function getTotalRefreshCost(
}
function updateGroupStatus(rg: RefreshGroupRecord): void {
- let allDone = fnutil.all(
+ const allDone = fnutil.all(
rg.statusPerCoin,
(x) => x === RefreshCoinStatus.Finished || x === RefreshCoinStatus.Frozen,
);
- let anyFrozen = fnutil.any(
+ const anyFrozen = fnutil.any(
rg.statusPerCoin,
(x) => x === RefreshCoinStatus.Frozen,
);
if (allDone) {
if (anyFrozen) {
rg.frozen = true;
- rg.retryInfo = resetRetryInfo();
+ rg.retryInfo = RetryInfo.reset();
} else {
rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now());
rg.operationStatus = OperationStatus.Finished;
- rg.retryInfo = resetRetryInfo();
+ rg.retryInfo = RetryInfo.reset();
}
}
}
@@ -753,7 +733,7 @@ async function setupRefreshRetry(
return;
}
if (options.reset) {
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
} else {
r.retryInfo = RetryInfo.increment(r.retryInfo);
}
@@ -987,7 +967,7 @@ export async function createRefreshGroup(
reason,
refreshGroupId,
refreshSessionPerCoin: oldCoinPubs.map(() => undefined),
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
inputPerCoin,
estimatedOutputPerCoin,
timestampCreated: TalerProtocolTimestamp.now(),
diff --git a/packages/taler-wallet-core/src/operations/refund.ts b/packages/taler-wallet-core/src/operations/refund.ts
index e5ce37a83..186fbf7d3 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -25,29 +25,18 @@
*/
import {
AbortingCoin,
- AbortRequest,
- AmountJson,
+ AbortRequest, AbsoluteTime, AmountJson,
Amounts,
ApplyRefundResponse,
codecForAbortResponse,
- codecForMerchantOrderRefundPickupResponse,
- CoinPublicKey,
- Logger,
+ codecForMerchantOrderRefundPickupResponse, codecForMerchantOrderStatusPaid, CoinPublicKey, Duration, Logger,
MerchantCoinRefundFailureStatus,
MerchantCoinRefundStatus,
MerchantCoinRefundSuccessStatus,
NotificationType,
- parseRefundUri,
- RefreshReason,
+ parseRefundUri, PrepareRefundResult, RefreshReason,
TalerErrorCode,
- TalerErrorDetail,
- URL,
- codecForMerchantOrderStatusPaid,
- AbsoluteTime,
- TalerProtocolTimestamp,
- Duration,
- PrepareRefundRequest,
- PrepareRefundResult,
+ TalerErrorDetail, TalerProtocolTimestamp, URL
} from "@gnu-taler/taler-util";
import {
AbortStatus,
@@ -55,19 +44,17 @@ import {
PurchaseRecord,
RefundReason,
RefundState,
- WalletStoresV1,
+ WalletStoresV1
} from "../db.js";
+import { InternalWalletState } from "../internal-wallet-state.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { checkDbInvariant } from "../util/invariants.js";
import { GetReadWriteAccess } from "../util/query.js";
import {
- resetRetryInfo,
- RetryInfo,
- updateRetryInfoTimeout,
+ RetryInfo
} from "../util/retries.js";
-import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
-import { InternalWalletState } from "../internal-wallet-state.js";
import { guardOperationException } from "./common.js";
+import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
const logger = new Logger("refund.ts");
@@ -147,7 +134,7 @@ async function setupPurchaseQueryRefundRetry(
return;
}
if (options.reset) {
- pr.refundStatusRetryInfo = resetRetryInfo();
+ pr.refundStatusRetryInfo = RetryInfo.reset();
} else {
pr.refundStatusRetryInfo = RetryInfo.increment(
pr.refundStatusRetryInfo,
@@ -500,7 +487,7 @@ async function acceptRefunds(
if (queryDone) {
p.timestampLastRefundStatus = now;
p.lastRefundStatusError = undefined;
- p.refundStatusRetryInfo = resetRetryInfo();
+ p.refundStatusRetryInfo = RetryInfo.reset();
p.refundQueryRequested = false;
if (p.abortStatus === AbortStatus.AbortRefund) {
p.abortStatus = AbortStatus.AbortFinished;
@@ -509,8 +496,7 @@ async function acceptRefunds(
} else {
// No error, but we need to try again!
p.timestampLastRefundStatus = now;
- p.refundStatusRetryInfo.retryCounter++;
- updateRetryInfoTimeout(p.refundStatusRetryInfo);
+ p.refundStatusRetryInfo = RetryInfo.increment(p.refundStatusRetryInfo)
p.lastRefundStatusError = undefined;
logger.trace("refund query not done");
}
@@ -619,7 +605,7 @@ export async function applyRefund(
}
p.refundQueryRequested = true;
p.lastRefundStatusError = undefined;
- p.refundStatusRetryInfo = resetRetryInfo();
+ p.refundStatusRetryInfo = RetryInfo.reset();
await tx.purchases.put(p);
return true;
});
@@ -892,7 +878,7 @@ export async function abortFailedPayWithRefund(
purchase.paymentSubmitPending = false;
purchase.abortStatus = AbortStatus.AbortRefund;
purchase.lastPayError = undefined;
- purchase.payRetryInfo = resetRetryInfo();
+ purchase.payRetryInfo = RetryInfo.reset();
await tx.purchases.put(purchase);
});
processPurchaseQueryRefund(ws, proposalId, {
diff --git a/packages/taler-wallet-core/src/operations/reserves.ts b/packages/taler-wallet-core/src/operations/reserves.ts
index 8e606bd60..8ee620d94 100644
--- a/packages/taler-wallet-core/src/operations/reserves.ts
+++ b/packages/taler-wallet-core/src/operations/reserves.ts
@@ -58,8 +58,6 @@ import {
} from "../util/http.js";
import { GetReadOnlyAccess } from "../util/query.js";
import {
- getRetryDuration,
- resetRetryInfo,
RetryInfo,
} from "../util/retries.js";
import {
@@ -100,7 +98,7 @@ async function setupReserveRetry(
return;
}
if (options.reset) {
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
} else {
r.retryInfo = RetryInfo.increment(r.retryInfo);
}
@@ -196,7 +194,7 @@ export async function createReserve(
timestampReserveInfoPosted: undefined,
bankInfo,
reserveStatus,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: undefined,
currency: req.amount.currency,
operationStatus: OperationStatus.Pending,
@@ -297,7 +295,7 @@ export async function forceQueryReserve(
case ReserveRecordStatus.Dormant:
reserve.reserveStatus = ReserveRecordStatus.QueryingStatus;
reserve.operationStatus = OperationStatus.Pending;
- reserve.retryInfo = resetRetryInfo();
+ reserve.retryInfo = RetryInfo.reset();
break;
default:
break;
@@ -392,7 +390,7 @@ async function registerReserveWithBank(
if (!r.bankInfo) {
throw Error("invariant failed");
}
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
await tx.reserves.put(r);
});
ws.notify({ type: NotificationType.ReserveRegisteredWithBank });
@@ -402,7 +400,7 @@ async function registerReserveWithBank(
export function getReserveRequestTimeout(r: ReserveRecord): Duration {
return durationMax(
{ d_ms: 60000 },
- durationMin({ d_ms: 5000 }, getRetryDuration(r.retryInfo)),
+ durationMin({ d_ms: 5000 }, RetryInfo.getDuration(r.retryInfo)),
);
}
@@ -459,7 +457,7 @@ async function processReserveBankStatus(
r.timestampBankConfirmed = now;
r.reserveStatus = ReserveRecordStatus.BankAborted;
r.operationStatus = OperationStatus.Finished;
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
await tx.reserves.put(r);
});
return;
@@ -496,7 +494,7 @@ async function processReserveBankStatus(
r.timestampBankConfirmed = now;
r.reserveStatus = ReserveRecordStatus.QueryingStatus;
r.operationStatus = OperationStatus.Pending;
- r.retryInfo = resetRetryInfo();
+ r.retryInfo = RetryInfo.reset();
} else {
switch (r.reserveStatus) {
case ReserveRecordStatus.WaitConfirmBank:
@@ -555,7 +553,7 @@ async function updateReserve(
if (
resp.status === 404 &&
result.talerErrorResponse.code ===
- TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
+ TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
) {
ws.notify({
type: NotificationType.ReserveNotYetFound,
@@ -662,7 +660,7 @@ async function updateReserve(
reservePub: reserve.reservePub,
rawWithdrawalAmount: remainingAmount,
timestampStart: AbsoluteTime.toTimestamp(AbsoluteTime.now()),
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: undefined,
denomsSel: denomSel,
secretSeed: encodeCrock(getRandomBytes(64)),
@@ -721,12 +719,13 @@ async function processReserveImpl(
case ReserveRecordStatus.RegisteringBank:
await processReserveBankStatus(ws, reservePub);
return await processReserveImpl(ws, reservePub, { forceNow: true });
- case ReserveRecordStatus.QueryingStatus:
+ case ReserveRecordStatus.QueryingStatus: {
const res = await updateReserve(ws, reservePub);
if (res.ready) {
return await processReserveImpl(ws, reservePub, { forceNow: true });
}
break;
+ }
case ReserveRecordStatus.Dormant:
// nothing to do
break;
diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts
index c0dcae911..da7673f35 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -18,51 +18,30 @@
* Imports.
*/
import {
- PrepareTipResult,
- parseTipUri,
- codecForTipPickupGetResponse,
- Amounts,
- TalerErrorDetail,
- NotificationType,
- TipPlanchetDetail,
- TalerErrorCode,
- Logger,
- URL,
- DenomKeyType,
- BlindedDenominationSignature,
- codecForMerchantTipResponseV2,
- TalerProtocolTimestamp,
+ Amounts, BlindedDenominationSignature,
+ codecForMerchantTipResponseV2, codecForTipPickupGetResponse, DenomKeyType, encodeCrock, getRandomBytes, j2s, Logger, NotificationType, parseTipUri, PrepareTipResult, TalerErrorCode, TalerErrorDetail, TalerProtocolTimestamp, TipPlanchetDetail, URL
} from "@gnu-taler/taler-util";
import { DerivedTipPlanchet } from "../crypto/cryptoTypes.js";
import {
- DenominationRecord,
CoinRecord,
CoinSourceType,
- CoinStatus,
- TipRecord,
+ CoinStatus, DenominationRecord, TipRecord
} from "../db.js";
-import { j2s } from "@gnu-taler/taler-util";
-import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
-import {
- resetRetryInfo,
- RetryInfo,
- updateRetryInfoTimeout,
-} from "../util/retries.js";
import { makeErrorDetail } from "../errors.js";
-import { updateExchangeFromUrl } from "./exchanges.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import {
- getExchangeWithdrawalInfo,
- updateWithdrawalDenoms,
- getCandidateWithdrawalDenoms,
- selectWithdrawalDenominations,
-} from "./withdraw.js";
-import {
getHttpResponseErrorDetails,
- readSuccessResponseJsonOrThrow,
+ readSuccessResponseJsonOrThrow
} from "../util/http.js";
-import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
+import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
+import {
+ RetryInfo
+} from "../util/retries.js";
import { guardOperationException } from "./common.js";
+import { updateExchangeFromUrl } from "./exchanges.js";
+import {
+ getCandidateWithdrawalDenoms, getExchangeWithdrawalInfo, selectWithdrawalDenominations, updateWithdrawalDenoms
+} from "./withdraw.js";
const logger = new Logger("operations/tip.ts");
@@ -130,7 +109,7 @@ export async function prepareTip(
createdTimestamp: TalerProtocolTimestamp.now(),
merchantTipId: res.merchantTipId,
tipAmountEffective: selectedDenoms.totalCoinValue,
- retryInfo: resetRetryInfo(),
+ retryInfo: RetryInfo.reset(),
lastError: undefined,
denomsSel: selectedDenoms,
pickedUpTimestamp: undefined,
@@ -202,7 +181,7 @@ async function setupTipRetry(
return;
}
if (options.reset) {
- t.retryInfo = resetRetryInfo();
+ t.retryInfo = RetryInfo.reset();
} else {
t.retryInfo = RetryInfo.increment(t.retryInfo);
}
@@ -237,7 +216,7 @@ async function resetTipRetry(
.runReadWrite(async (tx) => {
const x = await tx.tips.get(tipId);
if (x) {
- x.retryInfo = resetRetryInfo();
+ x.retryInfo = RetryInfo.reset();
await tx.tips.put(x);
}
});
@@ -430,7 +409,7 @@ async function processTipImpl(
}
tr.pickedUpTimestamp = TalerProtocolTimestamp.now();
tr.lastError = undefined;
- tr.retryInfo = resetRetryInfo();
+ tr.retryInfo = RetryInfo.reset();
await tx.tips.put(tr);
for (const cr of newCoinRecords) {
await tx.coins.put(cr);
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 2edc3ed98..ea9e22331 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -72,7 +72,7 @@ import {
readSuccessResponseJsonOrThrow,
} from "../util/http.js";
import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
import {
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
WALLET_EXCHANGE_PROTOCOL_VERSION,
@@ -215,7 +215,7 @@ export function selectWithdrawalDenominations(
for (const d of denoms) {
let count = 0;
const cost = Amounts.add(d.value, d.feeWithdraw).amount;
- for (;;) {
+ for (; ;) {
if (Amounts.cmp(remaining, cost) < 0) {
break;
}
@@ -875,11 +875,10 @@ export async function updateWithdrawalDenoms(
denom.verificationStatus === DenominationVerificationStatus.Unverified
) {
logger.trace(
- `Validating denomination (${current + 1}/${
- denominations.length
+ `Validating denomination (${current + 1}/${denominations.length
}) signature of ${denom.denomPubHash}`,
);
- let valid: boolean = false;
+ let valid = false;
if (ws.insecureTrustExchange) {
valid = true;
} else {
@@ -932,7 +931,7 @@ async function setupWithdrawalRetry(
return;
}
if (options.reset) {
- wsr.retryInfo = resetRetryInfo();
+ wsr.retryInfo = RetryInfo.reset();
} else {
wsr.retryInfo = RetryInfo.increment(wsr.retryInfo);
}
@@ -1097,7 +1096,7 @@ async function processWithdrawGroupImpl(
wg.timestampFinish = TalerProtocolTimestamp.now();
wg.operationStatus = OperationStatus.Finished;
delete wg.lastError;
- wg.retryInfo = resetRetryInfo();
+ wg.retryInfo = RetryInfo.reset();
}
await tx.withdrawalGroups.put(wg);
@@ -1203,7 +1202,7 @@ export async function getExchangeWithdrawalInfo(
) {
console.warn(
`wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
- `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`,
+ `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`,
);
}
}
diff --git a/packages/taler-wallet-core/src/util/retries.ts b/packages/taler-wallet-core/src/util/retries.ts
index 8b7d64406..965ba033a 100644
--- a/packages/taler-wallet-core/src/util/retries.ts
+++ b/packages/taler-wallet-core/src/util/retries.ts
@@ -41,7 +41,7 @@ const defaultRetryPolicy: RetryPolicy = {
maxTimeout: { d_ms: 6000 },
};
-export function updateRetryInfoTimeout(
+function updateTimeout(
r: RetryInfo,
p: RetryPolicy = defaultRetryPolicy,
): void {
@@ -65,45 +65,46 @@ export function updateRetryInfoTimeout(
r.nextRetry = { t_ms: t };
}
-export function getRetryDuration(
- r: RetryInfo | undefined,
- p: RetryPolicy = defaultRetryPolicy,
-): Duration {
- if (!r) {
- // If we don't have any retry info, run immediately.
- return { d_ms: 0 };
- }
- if (p.backoffDelta.d_ms === "forever") {
- return { d_ms: "forever" };
+export namespace RetryInfo {
+
+ export function getDuration(
+ r: RetryInfo | undefined,
+ p: RetryPolicy = defaultRetryPolicy,
+ ): Duration {
+ if (!r) {
+ // If we don't have any retry info, run immediately.
+ return { d_ms: 0 };
+ }
+ if (p.backoffDelta.d_ms === "forever") {
+ return { d_ms: "forever" };
+ }
+ const t = p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
+ return {
+ d_ms: p.maxTimeout.d_ms === "forever" ? t : Math.min(p.maxTimeout.d_ms, t),
+ };
}
- const t = p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
- return {
- d_ms: p.maxTimeout.d_ms === "forever" ? t : Math.min(p.maxTimeout.d_ms, t),
- };
-}
-export function resetRetryInfo(p: RetryPolicy = defaultRetryPolicy): RetryInfo {
- const now = AbsoluteTime.now();
- const info = {
- firstTry: now,
- nextRetry: now,
- retryCounter: 0,
- };
- updateRetryInfoTimeout(info, p);
- return info;
-}
+ export function reset(p: RetryPolicy = defaultRetryPolicy): RetryInfo {
+ const now = AbsoluteTime.now();
+ const info = {
+ firstTry: now,
+ nextRetry: now,
+ retryCounter: 0,
+ };
+ updateTimeout(info, p);
+ return info;
+ }
-export namespace RetryInfo {
export function increment(
r: RetryInfo | undefined,
p: RetryPolicy = defaultRetryPolicy,
- ) {
+ ): RetryInfo {
if (!r) {
- return resetRetryInfo(p);
+ return reset(p);
}
const r2 = { ...r };
r2.retryCounter++;
- updateRetryInfoTimeout(r2, p);
+ updateTimeout(r2, p);
return r2;
}
}
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 0590251e3..e2d504446 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -335,6 +335,7 @@ async function runTaskLoop(
let numGivingLiveness = 0;
let numDue = 0;
let minDue: AbsoluteTime = AbsoluteTime.never();
+
for (const p of pending.pendingOperations) {
minDue = AbsoluteTime.min(minDue, p.timestampDue);
if (AbsoluteTime.isExpired(p.timestampDue)) {
@@ -683,9 +684,13 @@ async function dumpCoins(ws: InternalWalletState): Promise<CoinDumpJson> {
c.exchangeBaseUrl,
c.denomPubHash,
);
+ if (!denomInfo) {
+ console.error("no denomination found for coin")
+ continue;
+ }
coinsJson.coins.push({
coin_pub: c.coinPub,
- denom_pub: denomInfo?.denomPub!,
+ denom_pub: denomInfo.denomPub,
denom_pub_hash: c.denomPubHash,
denom_value: Amounts.stringify(denom.value),
exchange_base_url: c.exchangeBaseUrl,