summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-09-13 16:08:51 +0200
committerFlorian Dold <florian@dold.me>2023-09-14 19:18:01 +0200
commitf4587c44fd6a6d76384cd671550890255c3fe650 (patch)
treef3eab7032e7ec4a6e49ffdf85ea57e3874b84130
parent59ef010b0e1f1eaf938a20a46f52d7c94af7b10d (diff)
downloadwallet-core-f4587c44fd6a6d76384cd671550890255c3fe650.tar.gz
wallet-core-f4587c44fd6a6d76384cd671550890255c3fe650.tar.bz2
wallet-core-f4587c44fd6a6d76384cd671550890255c3fe650.zip
wallet-core: use typed microsecond timestamps in DB
-rw-r--r--packages/taler-util/src/time.ts4
-rw-r--r--packages/taler-wallet-core/src/db.ts118
-rw-r--r--packages/taler-wallet-core/src/operations/attention.ts3
-rw-r--r--packages/taler-wallet-core/src/operations/backup/index.ts31
-rw-r--r--packages/taler-wallet-core/src/operations/deposits.ts9
-rw-r--r--packages/taler-wallet-core/src/operations/exchanges.ts7
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts15
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts27
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts3
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts46
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts3
-rw-r--r--packages/taler-wallet-core/src/operations/pending.ts3
-rw-r--r--packages/taler-wallet-core/src/operations/recoup.ts5
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts11
-rw-r--r--packages/taler-wallet-core/src/operations/reward.ts10
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts35
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts29
17 files changed, 216 insertions, 143 deletions
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 46ed37637..a63f9b296 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -52,6 +52,10 @@ export interface TalerProtocolTimestamp {
readonly _flavor?: typeof flavor_TalerProtocolTimestamp;
}
+/**
+ * Precise timestamp, typically used in the wallet-core
+ * API but not in other Taler APIs so far.
+ */
export interface TalerPreciseTimestamp {
/**
* Seconds (as integer) since epoch.
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index 9bf9a29cc..cebe3635b 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -28,7 +28,6 @@ import {
} from "@gnu-taler/idb-bridge";
import {
AgeCommitmentProof,
- AmountJson,
AmountString,
Amounts,
AttentionInfo,
@@ -45,12 +44,8 @@ import {
ExchangeAuditor,
ExchangeGlobalFees,
HashCodeString,
- InternationalizedString,
Logger,
- MerchantContractTerms,
- MerchantInfo,
PayCoinSelection,
- PeerContractTerms,
RefreshReason,
TalerErrorDetail,
TalerPreciseTimestamp,
@@ -151,6 +146,53 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
*/
export const WALLET_DB_MINOR_VERSION = 1;
+declare const symDbProtocolTimestamp: unique symbol;
+
+declare const symDbPreciseTimestamp: unique symbol;
+
+/**
+ * Timestamp, stored as microseconds.
+ *
+ * Always rounded to a full second.
+ */
+export type DbProtocolTimestamp = number & { [symDbProtocolTimestamp]: true };
+
+/**
+ * Timestamp, stored as microseconds.
+ */
+export type DbPreciseTimestamp = number & { [symDbPreciseTimestamp]: true };
+
+const DB_TIMESTAMP_FOREVER = Number.MAX_SAFE_INTEGER;
+
+export function timestampPreciseFromDb(
+ dbTs: DbPreciseTimestamp,
+): TalerPreciseTimestamp {
+ return TalerPreciseTimestamp.fromMilliseconds(Math.floor(dbTs / 1000));
+}
+
+export function timestampOptionalPreciseFromDb(
+ dbTs: DbPreciseTimestamp | undefined,
+): TalerPreciseTimestamp | undefined {
+ if (!dbTs) {
+ return undefined;
+ }
+ return TalerPreciseTimestamp.fromMilliseconds(Math.floor(dbTs / 1000));
+}
+
+export function timestampPreciseToDb(
+ stamp: TalerPreciseTimestamp,
+): DbPreciseTimestamp {
+ if (stamp.t_s === "never") {
+ return DB_TIMESTAMP_FOREVER as DbPreciseTimestamp;
+ } else {
+ let tUs = stamp.t_s * 1000000;
+ if (stamp.off_us) {
+ tUs == stamp.off_us;
+ }
+ return tUs as DbPreciseTimestamp;
+ }
+}
+
/**
* Format of the operation status code: 0x0abc_nnnn
@@ -217,7 +259,7 @@ export enum WithdrawalGroupStatus {
* Exchange is doing AML checks.
*/
PendingAml = 0x0100_0006,
- SuspendedAml = 0x0100_0006,
+ SuspendedAml = 0x0110_0006,
/**
* The corresponding withdraw record has been created.
@@ -268,14 +310,14 @@ export interface ReserveBankInfo {
*
* Set to undefined if that hasn't happened yet.
*/
- timestampReserveInfoPosted: TalerPreciseTimestamp | undefined;
+ timestampReserveInfoPosted: DbPreciseTimestamp | undefined;
/**
* Time when the reserve was confirmed by the bank.
*
* Set to undefined if not confirmed yet.
*/
- timestampBankConfirmed: TalerPreciseTimestamp | undefined;
+ timestampBankConfirmed: DbPreciseTimestamp | undefined;
}
/**
@@ -488,7 +530,7 @@ export interface ExchangeDetailsRecord {
tosAccepted:
| {
etag: string;
- timestamp: TalerPreciseTimestamp;
+ timestamp: DbPreciseTimestamp;
}
| undefined;
@@ -528,7 +570,7 @@ export interface ExchangeDetailsPointer {
* Timestamp when the (masterPublicKey, currency) pointer
* has been updated.
*/
- updateClock: TalerPreciseTimestamp;
+ updateClock: DbPreciseTimestamp;
}
export enum ExchangeEntryDbRecordStatus {
@@ -567,7 +609,7 @@ export interface ExchangeEntryRecord {
*
* Used mostly in the UI to suggest exchanges.
*/
- lastWithdrawal?: TalerPreciseTimestamp;
+ lastWithdrawal?: DbPreciseTimestamp;
/**
* Pointer to the current exchange details.
@@ -588,7 +630,7 @@ export interface ExchangeEntryRecord {
/**
* Last time when the exchange /keys info was updated.
*/
- lastUpdate: TalerPreciseTimestamp | undefined;
+ lastUpdate: DbPreciseTimestamp | undefined;
/**
* Next scheduled update for the exchange.
@@ -816,7 +858,7 @@ export interface RewardRecord {
* Has the user accepted the tip? Only after the tip has been accepted coins
* withdrawn from the tip may be used.
*/
- acceptedTimestamp: TalerPreciseTimestamp | undefined;
+ acceptedTimestamp: DbPreciseTimestamp | undefined;
/**
* The tipped amount.
@@ -869,7 +911,7 @@ export interface RewardRecord {
*/
merchantRewardId: string;
- createdTimestamp: TalerPreciseTimestamp;
+ createdTimestamp: DbPreciseTimestamp;
/**
* The url to be redirected after the tip is accepted.
@@ -880,7 +922,7 @@ export interface RewardRecord {
* Timestamp for when the wallet finished picking up the tip
* from the merchant.
*/
- pickedUpTimestamp: TalerPreciseTimestamp | undefined;
+ pickedUpTimestamp: DbPreciseTimestamp | undefined;
status: RewardRecordStatus;
}
@@ -978,12 +1020,12 @@ export interface RefreshGroupRecord {
*/
statusPerCoin: RefreshCoinStatus[];
- timestampCreated: TalerPreciseTimestamp;
+ timestampCreated: DbPreciseTimestamp;
/**
* Timestamp when the refresh session finished.
*/
- timestampFinished: TalerPreciseTimestamp | undefined;
+ timestampFinished: DbPreciseTimestamp | undefined;
}
/**
@@ -1208,7 +1250,7 @@ export interface PurchaseRecord {
* Timestamp of the first time that sending a payment to the merchant
* for this purchase was successful.
*/
- timestampFirstSuccessfulPay: TalerPreciseTimestamp | undefined;
+ timestampFirstSuccessfulPay: DbPreciseTimestamp | undefined;
merchantPaySig: string | undefined;
@@ -1223,19 +1265,19 @@ export interface PurchaseRecord {
/**
* When was the purchase record created?
*/
- timestamp: TalerPreciseTimestamp;
+ timestamp: DbPreciseTimestamp;
/**
* When was the purchase made?
* Refers to the time that the user accepted.
*/
- timestampAccept: TalerPreciseTimestamp | undefined;
+ timestampAccept: DbPreciseTimestamp | undefined;
/**
* When was the last refund made?
* Set to 0 if no refund was made on the purchase.
*/
- timestampLastRefundStatus: TalerPreciseTimestamp | undefined;
+ timestampLastRefundStatus: DbPreciseTimestamp | undefined;
/**
* Last session signature that we submitted to /pay (if any).
@@ -1285,12 +1327,12 @@ export interface WalletBackupConfState {
/**
* Timestamp stored in the last backup.
*/
- lastBackupTimestamp?: TalerPreciseTimestamp;
+ lastBackupTimestamp?: DbPreciseTimestamp;
/**
* Last time we tried to do a backup.
*/
- lastBackupCheckTimestamp?: TalerPreciseTimestamp;
+ lastBackupCheckTimestamp?: DbPreciseTimestamp;
lastBackupNonce?: string;
}
@@ -1398,12 +1440,12 @@ export interface WithdrawalGroupRecord {
* When was the withdrawal operation started started?
* Timestamp in milliseconds.
*/
- timestampStart: TalerPreciseTimestamp;
+ timestampStart: DbPreciseTimestamp;
/**
* When was the withdrawal operation completed?
*/
- timestampFinish?: TalerPreciseTimestamp;
+ timestampFinish?: DbPreciseTimestamp;
/**
* Current status of the reserve.
@@ -1494,9 +1536,9 @@ export interface RecoupGroupRecord {
exchangeBaseUrl: string;
- timestampStarted: TalerPreciseTimestamp;
+ timestampStarted: DbPreciseTimestamp;
- timestampFinished: TalerPreciseTimestamp | undefined;
+ timestampFinished: DbPreciseTimestamp | undefined;
/**
* Public keys that identify the coins being recouped
@@ -1530,7 +1572,7 @@ export type BackupProviderState =
}
| {
tag: BackupProviderStateTag.Ready;
- nextBackupTimestamp: TalerPreciseTimestamp;
+ nextBackupTimestamp: DbPreciseTimestamp;
}
| {
tag: BackupProviderStateTag.Retrying;
@@ -1575,7 +1617,7 @@ export interface BackupProviderRecord {
* Does NOT correspond to the timestamp of the backup,
* which only changes when the backup content changes.
*/
- lastBackupCycleTimestamp?: TalerPreciseTimestamp;
+ lastBackupCycleTimestamp?: DbPreciseTimestamp;
/**
* Proposal that we're currently trying to pay for.
@@ -1678,9 +1720,9 @@ export interface DepositGroupRecord {
*/
counterpartyEffectiveDepositAmount: AmountString;
- timestampCreated: TalerPreciseTimestamp;
+ timestampCreated: DbPreciseTimestamp;
- timestampFinished: TalerPreciseTimestamp | undefined;
+ timestampFinished: DbPreciseTimestamp | undefined;
operationStatus: DepositOperationStatus;
@@ -1791,7 +1833,7 @@ export interface PeerPushDebitRecord {
purseExpiration: TalerProtocolTimestamp;
- timestampCreated: TalerPreciseTimestamp;
+ timestampCreated: DbPreciseTimestamp;
abortRefreshGroupId?: string;
@@ -1864,7 +1906,7 @@ export interface PeerPullCreditRecord {
contractEncNonce: string;
- mergeTimestamp: TalerPreciseTimestamp;
+ mergeTimestamp: DbPreciseTimestamp;
mergeReserveRowId: number;
@@ -1916,7 +1958,7 @@ export interface PeerPushPaymentIncomingRecord {
contractPriv: string;
- timestamp: TalerPreciseTimestamp;
+ timestamp: DbPreciseTimestamp;
estimatedAmountEffective: AmountString;
@@ -1988,7 +2030,7 @@ export interface PeerPullPaymentIncomingRecord {
contractTermsHash: string;
- timestampCreated: TalerPreciseTimestamp;
+ timestampCreated: DbPreciseTimestamp;
/**
* Contract priv that we got from the other party.
@@ -2095,7 +2137,7 @@ export interface UserAttentionRecord {
/**
* When the user mark this notification as read.
*/
- read: TalerPreciseTimestamp | undefined;
+ read: DbPreciseTimestamp | undefined;
}
export interface DbExchangeHandle {
@@ -2139,7 +2181,7 @@ export interface RefundGroupRecord {
/**
* Timestamp when the refund group was created.
*/
- timestampCreated: TalerPreciseTimestamp;
+ timestampCreated: DbPreciseTimestamp;
proposalId: string;
@@ -2196,7 +2238,7 @@ export interface RefundItemRecord {
/**
* Time when the wallet became aware of the refund.
*/
- obtainedTime: TalerPreciseTimestamp;
+ obtainedTime: DbPreciseTimestamp;
refundAmount: AmountString;
diff --git a/packages/taler-wallet-core/src/operations/attention.ts b/packages/taler-wallet-core/src/operations/attention.ts
index 7d84b43ef..1030db0a6 100644
--- a/packages/taler-wallet-core/src/operations/attention.ts
+++ b/packages/taler-wallet-core/src/operations/attention.ts
@@ -31,6 +31,7 @@ import {
UserAttentionUnreadList,
} from "@gnu-taler/taler-util";
import { InternalWalletState } from "../internal-wallet-state.js";
+import { timestampPreciseToDb } from "../index.js";
const logger = new Logger("operations/attention.ts");
@@ -94,7 +95,7 @@ export async function markAttentionRequestAsRead(
if (!ua) throw Error("attention request not found");
tx.userAttention.put({
...ua,
- read: TalerPreciseTimestamp.now(),
+ read: timestampPreciseToDb(TalerPreciseTimestamp.now()),
});
});
}
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts
index a5e8dbd42..7a2771c57 100644
--- a/packages/taler-wallet-core/src/operations/backup/index.ts
+++ b/packages/taler-wallet-core/src/operations/backup/index.ts
@@ -84,6 +84,9 @@ import {
ConfigRecord,
ConfigRecordKey,
WalletBackupConfState,
+ timestampOptionalPreciseFromDb,
+ timestampPreciseFromDb,
+ timestampPreciseToDb,
} from "../../db.js";
import { InternalWalletState } from "../../internal-wallet-state.js";
import { assertUnreachable } from "../../util/assertUnreachable.js";
@@ -259,10 +262,12 @@ async function runBackupCycleForProvider(
if (!prov) {
return;
}
- prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now();
+ prov.lastBackupCycleTimestamp = timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ );
prov.state = {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: getNextBackupTimestamp(),
+ nextBackupTimestamp: timestampPreciseToDb(getNextBackupTimestamp()),
};
await tx.backupProviders.put(prov);
});
@@ -361,10 +366,12 @@ async function runBackupCycleForProvider(
return;
}
prov.lastBackupHash = encodeCrock(currentBackupHash);
- prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now();
+ prov.lastBackupCycleTimestamp = timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ );
prov.state = {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: getNextBackupTimestamp(),
+ nextBackupTimestamp: timestampPreciseToDb(getNextBackupTimestamp()),
};
await tx.backupProviders.put(prov);
});
@@ -594,7 +601,9 @@ export async function addBackupProvider(
if (req.activate) {
oldProv.state = {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: TalerPreciseTimestamp.now(),
+ nextBackupTimestamp: timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ ),
};
logger.info("setting existing backup provider to active");
await tx.backupProviders.put(oldProv);
@@ -616,7 +625,9 @@ export async function addBackupProvider(
if (req.activate) {
state = {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: TalerPreciseTimestamp.now(),
+ nextBackupTimestamp: timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ ),
};
} else {
state = {
@@ -840,7 +851,9 @@ export async function getBackupInfo(
providers.push({
active: x.provider.state.tag !== BackupProviderStateTag.Provisional,
syncProviderBaseUrl: x.provider.baseUrl,
- lastSuccessfulBackupTimestamp: x.provider.lastBackupCycleTimestamp,
+ lastSuccessfulBackupTimestamp: timestampOptionalPreciseFromDb(
+ x.provider.lastBackupCycleTimestamp,
+ ),
paymentProposalIds: x.provider.paymentProposalIds,
lastError:
x.provider.state.tag === BackupProviderStateTag.Retrying
@@ -917,7 +930,9 @@ async function backupRecoveryTheirs(
shouldRetryFreshProposal: false,
state: {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: TalerPreciseTimestamp.now(),
+ nextBackupTimestamp: timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ ),
},
uids: [encodeCrock(getRandomBytes(32))],
});
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts
index 2de8f30a1..cb40f8f22 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -73,6 +73,7 @@ import {
RefreshOperationStatus,
createRefreshGroup,
getTotalRefreshCost,
+ timestampPreciseToDb,
} from "../index.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { assertUnreachable } from "../util/assertUnreachable.js";
@@ -857,7 +858,9 @@ async function processDepositGroupPendingTrack(
}
}
if (allWired) {
- dg.timestampFinished = TalerPreciseTimestamp.now();
+ dg.timestampFinished = timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ );
dg.operationStatus = DepositOperationStatus.Finished;
await tx.depositGroups.put(dg);
}
@@ -1375,7 +1378,9 @@ export async function createDepositGroup(
amount: contractData.amount,
noncePriv: noncePair.priv,
noncePub: noncePair.pub,
- timestampCreated: AbsoluteTime.toPreciseTimestamp(now),
+ timestampCreated: timestampPreciseToDb(
+ AbsoluteTime.toPreciseTimestamp(now),
+ ),
timestampFinished: undefined,
statusPerCoin: payCoinSel.coinSel.coinPubs.map(
() => DepositElementStatus.DepositPending,
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts
index 43a08ed3b..60d55252a 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -74,6 +74,7 @@ import {
ExchangeEntryDbRecordStatus,
ExchangeEntryDbUpdateStatus,
isWithdrawableDenom,
+ timestampPreciseToDb,
WalletDbReadWriteTransaction,
} from "../index.js";
import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js";
@@ -174,7 +175,7 @@ export async function acceptExchangeTermsOfService(
if (d) {
d.tosAccepted = {
etag: etag || d.tosCurrentEtag,
- timestamp: TalerPreciseTimestamp.now(),
+ timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
};
await tx.exchangeDetails.put(d);
}
@@ -753,7 +754,7 @@ export async function updateExchangeFromUrlHandler(
if (existingDetails?.rowId) {
newDetails.rowId = existingDetails.rowId;
}
- r.lastUpdate = TalerPreciseTimestamp.now();
+ r.lastUpdate = timestampPreciseToDb(TalerPreciseTimestamp.now());
r.nextUpdateStampMs = AbsoluteTime.toStampMs(
AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry),
);
@@ -763,7 +764,7 @@ export async function updateExchangeFromUrlHandler(
r.detailsPointer = {
currency: newDetails.currency,
masterPublicKey: newDetails.masterPublicKey,
- updateClock: TalerPreciseTimestamp.now(),
+ updateClock: timestampPreciseToDb(TalerPreciseTimestamp.now()),
};
}
await tx.exchanges.put(r);
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index fe0cbeda0..97bf6e2a6 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -103,6 +103,7 @@ import {
RefundGroupStatus,
RefundItemRecord,
RefundItemStatus,
+ timestampPreciseToDb,
} from "../index.js";
import {
EXCHANGE_COINS_LOCK,
@@ -644,7 +645,7 @@ async function createPurchase(
noncePriv: priv,
noncePub: pub,
claimToken,
- timestamp: TalerPreciseTimestamp.now(),
+ timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
merchantBaseUrl,
orderId,
proposalId: proposalId,
@@ -717,7 +718,7 @@ async function storeFirstPaySuccess(
if (purchase.purchaseStatus === PurchaseStatus.PendingPaying) {
purchase.purchaseStatus = PurchaseStatus.Done;
}
- purchase.timestampFirstSuccessfulPay = now;
+ purchase.timestampFirstSuccessfulPay = timestampPreciseToDb(now);
purchase.lastSessionId = sessionId;
purchase.merchantPaySig = payResponse.sig;
purchase.posConfirmation = payResponse.pos_confirmation;
@@ -941,7 +942,9 @@ async function unblockBackup(
.forEachAsync(async (bp) => {
bp.state = {
tag: BackupProviderStateTag.Ready,
- nextBackupTimestamp: TalerPreciseTimestamp.now(),
+ nextBackupTimestamp: timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ ),
};
tx.backupProviders.put(bp);
});
@@ -1447,7 +1450,7 @@ export async function confirmPay(
totalPayCost: Amounts.stringify(payCostInfo),
};
p.lastSessionId = sessionId;
- p.timestampAccept = TalerPreciseTimestamp.now();
+ p.timestampAccept = timestampPreciseToDb(TalerPreciseTimestamp.now());
p.purchaseStatus = PurchaseStatus.PendingPaying;
await tx.purchases.put(p);
await spendCoins(ws, tx, {
@@ -2791,7 +2794,7 @@ async function storeRefunds(
proposalId: purchase.proposalId,
refundGroupId: newRefundGroupId,
status: RefundGroupStatus.Pending,
- timestampCreated: now,
+ timestampCreated: timestampPreciseToDb(now),
amountEffective: Amounts.stringify(
Amounts.zeroOfCurrency(currency),
),
@@ -2802,7 +2805,7 @@ async function storeRefunds(
const newItem: RefundItemRecord = {
coinPub: rf.coin_pub,
executionTime: rf.execution_time,
- obtainedTime: now,
+ obtainedTime: timestampPreciseToDb(now),
refundAmount: rf.refund_amount,
refundGroupId: newGroup.refundGroupId,
rtxid: rf.rtransaction_id,
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts
index 0355eb152..6ec8822ab 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts
@@ -60,6 +60,9 @@ import {
PeerPullPaymentCreditStatus,
WithdrawalGroupStatus,
WithdrawalRecordType,
+ timestampOptionalPreciseFromDb,
+ timestampPreciseFromDb,
+ timestampPreciseToDb,
updateExchangeFromUrl,
} from "../index.js";
import { InternalWalletState } from "../internal-wallet-state.js";
@@ -395,12 +398,14 @@ async function handlePeerPullCreditCreatePurse(
nonce: pullIni.contractEncNonce,
});
+ const mergeTimestamp = timestampPreciseFromDb(pullIni.mergeTimestamp);
+
const purseExpiration = contractTerms.purse_expiration;
const sigRes = await ws.cryptoApi.signReservePurseCreate({
contractTermsHash: pullIni.contractTermsHash,
flags: WalletAccountMergeFlags.CreateWithPurseFee,
mergePriv: pullIni.mergePriv,
- mergeTimestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp),
+ mergeTimestamp: TalerPreciseTimestamp.round(mergeTimestamp),
purseAmount: pullIni.amount,
purseExpiration: purseExpiration,
purseFee: purseFee,
@@ -412,7 +417,7 @@ async function handlePeerPullCreditCreatePurse(
const reservePurseReqBody: ExchangeReservePurseRequest = {
merge_sig: sigRes.mergeSig,
- merge_timestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp),
+ merge_timestamp: TalerPreciseTimestamp.round(mergeTimestamp),
h_contract_terms: pullIni.contractTermsHash,
merge_pub: pullIni.mergePub,
min_age: 0,
@@ -695,11 +700,17 @@ async function getPreferredExchangeForCurrency(
if (candidate.lastWithdrawal && !e.lastWithdrawal) {
continue;
}
- if (candidate.lastWithdrawal && e.lastWithdrawal) {
+ const exchangeLastWithdrawal = timestampOptionalPreciseFromDb(
+ e.lastWithdrawal,
+ );
+ const candidateLastWithdrawal = timestampOptionalPreciseFromDb(
+ candidate.lastWithdrawal,
+ );
+ if (exchangeLastWithdrawal && candidateLastWithdrawal) {
if (
AbsoluteTime.cmp(
- AbsoluteTime.fromPreciseTimestamp(e.lastWithdrawal),
- AbsoluteTime.fromPreciseTimestamp(candidate.lastWithdrawal),
+ AbsoluteTime.fromPreciseTimestamp(exchangeLastWithdrawal),
+ AbsoluteTime.fromPreciseTimestamp(candidateLastWithdrawal),
) > 0
) {
candidate = e;
@@ -741,8 +752,6 @@ export async function initiatePeerPullPayment(
exchangeBaseUrl: exchangeBaseUrl,
});
- const mergeTimestamp = TalerPreciseTimestamp.now();
-
const pursePair = await ws.cryptoApi.createEddsaKeypair({});
const mergePair = await ws.cryptoApi.createEddsaKeypair({});
@@ -766,6 +775,8 @@ export async function initiatePeerPullPayment(
undefined,
);
+ const mergeTimestamp = TalerPreciseTimestamp.now();
+
const transitionInfo = await ws.db
.mktx((x) => [x.peerPullCredit, x.contractTerms])
.runReadWrite(async (tx) => {
@@ -778,7 +789,7 @@ export async function initiatePeerPullPayment(
mergePriv: mergePair.priv,
mergePub: mergePair.pub,
status: PeerPullPaymentCreditStatus.PendingCreatePurse,
- mergeTimestamp,
+ mergeTimestamp: timestampPreciseToDb(mergeTimestamp),
contractEncNonce,
mergeReserveRowId: mergeReserveRowId,
contractPriv: contractKeyPair.priv,
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
index 5bcfa3418..48cbf574f 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
@@ -59,6 +59,7 @@ import {
PendingTaskType,
RefreshOperationStatus,
createRefreshGroup,
+ timestampPreciseToDb,
} from "../index.js";
import { assertUnreachable } from "../util/assertUnreachable.js";
import { checkLogicInvariant } from "../util/invariants.js";
@@ -595,7 +596,7 @@ export async function preparePeerPullDebit(
contractPriv: contractPriv,
exchangeBaseUrl: exchangeBaseUrl,
pursePub: pursePub,
- timestampCreated: TalerPreciseTimestamp.now(),
+ timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()),
contractTermsHash,
amount: contractTerms.amount,
status: PeerPullDebitRecordStatus.DialogProposed,
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
index 89d9e3b49..e4698c203 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
@@ -59,6 +59,7 @@ import {
PendingTaskType,
WithdrawalGroupStatus,
WithdrawalRecordType,
+ timestampPreciseToDb,
} from "../index.js";
import { assertUnreachable } from "../util/assertUnreachable.js";
import { checkDbInvariant } from "../util/invariants.js";
@@ -129,12 +130,10 @@ export async function preparePeerPushCredit(
amountEffective: existing.existingPushInc.estimatedAmountEffective,
amountRaw: existing.existingContractTerms.amount,
contractTerms: existing.existingContractTerms,
- peerPushCreditId:
- existing.existingPushInc.peerPushCreditId,
+ peerPushCreditId: existing.existingPushInc.peerPushCreditId,
transactionId: constructTransactionIdentifier({
tag: TransactionType.PeerPushCredit,
- peerPushCreditId:
- existing.existingPushInc.peerPushCreditId,
+ peerPushCreditId: existing.existingPushInc.peerPushCreditId,
}),
};
}
@@ -196,7 +195,7 @@ export async function preparePeerPushCredit(
exchangeBaseUrl: exchangeBaseUrl,
mergePriv: dec.mergePriv,
pursePub: pursePub,
- timestamp: TalerPreciseTimestamp.now(),
+ timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
contractTermsHash,
status: PeerPushCreditStatus.DialogProposed,
withdrawalGroupId,
@@ -263,16 +262,11 @@ async function longpollKycStatus(
const transitionInfo = await ws.db
.mktx((x) => [x.peerPushCredit])
.runReadWrite(async (tx) => {
- const peerInc = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const peerInc = await tx.peerPushCredit.get(peerPushCreditId);
if (!peerInc) {
return;
}
- if (
- peerInc.status !==
- PeerPushCreditStatus.PendingMergeKycRequired
- ) {
+ if (peerInc.status !== PeerPushCreditStatus.PendingMergeKycRequired) {
return;
}
const oldTxState = computePeerPushCreditTransactionState(peerInc);
@@ -333,9 +327,7 @@ async function processPeerPushCreditKycRequired(
const { transitionInfo, result } = await ws.db
.mktx((x) => [x.peerPushCredit])
.runReadWrite(async (tx) => {
- const peerInc = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const peerInc = await tx.peerPushCredit.get(peerPushCreditId);
if (!peerInc) {
return {
transitionInfo: undefined,
@@ -466,9 +458,7 @@ async function handlePendingMerge(
x.exchangeDetails,
])
.runReadWrite(async (tx) => {
- const peerInc = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const peerInc = await tx.peerPushCredit.get(peerPushCreditId);
if (!peerInc) {
return undefined;
}
@@ -520,9 +510,7 @@ async function handlePendingWithdrawing(
const transitionInfo = await ws.db
.mktx((x) => [x.peerPushCredit, x.withdrawalGroups])
.runReadWrite(async (tx) => {
- const ppi = await tx.peerPushCredit.get(
- peerInc.peerPushCreditId,
- );
+ const ppi = await tx.peerPushCredit.get(peerInc.peerPushCreditId);
if (!ppi) {
finished = true;
return;
@@ -631,9 +619,7 @@ export async function confirmPeerPushCredit(
}
peerPushCreditId = parsedTx.peerPushCreditId;
} else {
- throw Error(
- "no transaction ID (or deprecated peerPushCreditId) provided",
- );
+ throw Error("no transaction ID (or deprecated peerPushCreditId) provided");
}
await ws.db
@@ -683,9 +669,7 @@ export async function suspendPeerPushCreditTransaction(
const transitionInfo = await ws.db
.mktx((x) => [x.peerPushCredit])
.runReadWrite(async (tx) => {
- const pushCreditRec = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId);
if (!pushCreditRec) {
logger.warn(`peer push credit ${peerPushCreditId} not found`);
return;
@@ -746,9 +730,7 @@ export async function abortPeerPushCreditTransaction(
const transitionInfo = await ws.db
.mktx((x) => [x.peerPushCredit])
.runReadWrite(async (tx) => {
- const pushCreditRec = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId);
if (!pushCreditRec) {
logger.warn(`peer push credit ${peerPushCreditId} not found`);
return;
@@ -820,9 +802,7 @@ export async function resumePeerPushCreditTransaction(
const transitionInfo = await ws.db
.mktx((x) => [x.peerPushCredit])
.runReadWrite(async (tx) => {
- const pushCreditRec = await tx.peerPushCredit.get(
- peerPushCreditId,
- );
+ const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId);
if (!pushCreditRec) {
logger.warn(`peer push credit ${peerPushCreditId} not found`);
return;
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts
index e80ffc059..b3d0eb132 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts
@@ -55,6 +55,7 @@ import {
PeerPushDebitStatus,
RefreshOperationStatus,
createRefreshGroup,
+ timestampPreciseToDb,
} from "../index.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { PendingTaskType } from "../pending-types.js";
@@ -669,7 +670,7 @@ export async function initiatePeerPushDebit(
purseExpiration: purseExpiration,
pursePriv: pursePair.priv,
pursePub: pursePair.pub,
- timestampCreated: TalerPreciseTimestamp.now(),
+ timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()),
status: PeerPushDebitStatus.PendingCreatePurse,
contractEncNonce,
coinSel: {
diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts
index 6115f848b..120d316ce 100644
--- a/packages/taler-wallet-core/src/operations/pending.ts
+++ b/packages/taler-wallet-core/src/operations/pending.ts
@@ -47,6 +47,7 @@ import {
ExchangeEntryDbUpdateStatus,
RefreshOperationStatus,
DepositElementStatus,
+ timestampPreciseFromDb,
} from "../db.js";
import {
PendingOperationsResponse,
@@ -445,7 +446,7 @@ async function gatherBackupPending(
const retryRecord = await tx.operationRetries.get(opId);
if (bp.state.tag === BackupProviderStateTag.Ready) {
const timestampDue = AbsoluteTime.fromPreciseTimestamp(
- bp.state.nextBackupTimestamp,
+ timestampPreciseFromDb(bp.state.nextBackupTimestamp),
);
resp.pendingOperations.push({
type: PendingTaskType.Backup,
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts
index 6a18e5de6..782e98d1c 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -47,6 +47,7 @@ import {
WithdrawCoinSource,
WithdrawalGroupStatus,
WithdrawalRecordType,
+ timestampPreciseToDb,
} from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { checkDbInvariant } from "../util/invariants.js";
@@ -391,7 +392,7 @@ export async function processRecoupGroup(
if (!rg2) {
return;
}
- rg2.timestampFinished = TalerPreciseTimestamp.now();
+ rg2.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now());
if (rg2.scheduleRefreshCoins.length > 0) {
const refreshGroupId = await createRefreshGroup(
ws,
@@ -424,7 +425,7 @@ export async function createRecoupGroup(
exchangeBaseUrl: exchangeBaseUrl,
coinPubs: coinPubs,
timestampFinished: undefined,
- timestampStarted: TalerPreciseTimestamp.now(),
+ timestampStarted: timestampPreciseToDb(TalerPreciseTimestamp.now()),
recoupFinishedPerCoin: coinPubs.map(() => false),
scheduleRefreshCoins: [],
};
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts
index 75adbc860..dc1d53627 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -80,6 +80,7 @@ import {
isWithdrawableDenom,
PendingTaskType,
RefreshSessionRecord,
+ timestampPreciseToDb,
} from "../index.js";
import {
EXCHANGE_COINS_LOCK,
@@ -157,10 +158,10 @@ function updateGroupStatus(rg: RefreshGroupRecord): { final: boolean } {
);
if (allFinal) {
if (anyFailed) {
- rg.timestampFinished = TalerPreciseTimestamp.now();
+ rg.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now());
rg.operationStatus = RefreshOperationStatus.Failed;
} else {
- rg.timestampFinished = TalerPreciseTimestamp.now();
+ rg.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now());
rg.operationStatus = RefreshOperationStatus.Finished;
}
return { final: true };
@@ -1099,12 +1100,14 @@ export async function createRefreshGroup(
expectedOutputPerCoin: estimatedOutputPerCoin.map((x) =>
Amounts.stringify(x),
),
- timestampCreated: TalerPreciseTimestamp.now(),
+ timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()),
};
if (oldCoinPubs.length == 0) {
logger.warn("created refresh group with zero coins");
- refreshGroup.timestampFinished = TalerPreciseTimestamp.now();
+ refreshGroup.timestampFinished = timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ );
refreshGroup.operationStatus = RefreshOperationStatus.Finished;
}
diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts
index 6ae021174..3681dc4f5 100644
--- a/packages/taler-wallet-core/src/operations/reward.ts
+++ b/packages/taler-wallet-core/src/operations/reward.ts
@@ -50,6 +50,8 @@ import {
DenominationRecord,
RewardRecord,
RewardRecordStatus,
+ timestampPreciseFromDb,
+ timestampPreciseToDb,
} from "../db.js";
import { makeErrorDetail } from "@gnu-taler/taler-util";
import { InternalWalletState } from "../internal-wallet-state.js";
@@ -203,7 +205,7 @@ export async function prepareTip(
exchangeBaseUrl: tipPickupStatus.exchange_url,
next_url: tipPickupStatus.next_url,
merchantBaseUrl: res.merchantBaseUrl,
- createdTimestamp: TalerPreciseTimestamp.now(),
+ createdTimestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
merchantRewardId: res.merchantRewardId,
rewardAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue),
denomsSel: selectedDenoms,
@@ -411,7 +413,7 @@ export async function processTip(
return;
}
const oldTxState = computeRewardTransactionStatus(tr);
- tr.pickedUpTimestamp = TalerPreciseTimestamp.now();
+ tr.pickedUpTimestamp = timestampPreciseToDb(TalerPreciseTimestamp.now());
tr.status = RewardRecordStatus.Done;
await tx.rewards.put(tr);
const newTxState = computeRewardTransactionStatus(tr);
@@ -448,7 +450,9 @@ export async function acceptTip(
return { tipRecord };
}
const oldTxState = computeRewardTransactionStatus(tipRecord);
- tipRecord.acceptedTimestamp = TalerPreciseTimestamp.now();
+ tipRecord.acceptedTimestamp = timestampPreciseToDb(
+ TalerPreciseTimestamp.now(),
+ );
tipRecord.status = RewardRecordStatus.PendingPickup;
await tx.rewards.put(tipRecord);
const newTxState = computeRewardTransactionStatus(tipRecord);
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index d7b277faf..41bdae249 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -65,7 +65,12 @@ import {
WithdrawalGroupStatus,
WithdrawalRecordType,
} from "../db.js";
-import { GetReadOnlyAccess, WalletStoresV1 } from "../index.js";
+import {
+ GetReadOnlyAccess,
+ timestampOptionalPreciseFromDb,
+ timestampPreciseFromDb,
+ WalletStoresV1,
+} from "../index.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { PendingTaskType } from "../pending-types.js";
import { assertUnreachable } from "../util/assertUnreachable.js";
@@ -470,7 +475,7 @@ function buildTransactionForPushPaymentDebit(
expiration: contractTerms.purse_expiration,
summary: contractTerms.summary,
},
- timestamp: pi.timestampCreated,
+ timestamp: timestampPreciseFromDb(pi.timestampCreated),
talerUri: stringifyPayPushUri({
exchangeBaseUrl: pi.exchangeBaseUrl,
contractPriv: pi.contractPriv,
@@ -501,7 +506,7 @@ function buildTransactionForPullPaymentDebit(
expiration: contractTerms.purse_expiration,
summary: contractTerms.summary,
},
- timestamp: pi.timestampCreated,
+ timestamp: timestampPreciseFromDb(pi.timestampCreated),
transactionId: constructTransactionIdentifier({
tag: TransactionType.PeerPullDebit,
peerPullDebitId: pi.peerPullDebitId,
@@ -543,8 +548,7 @@ function buildTransactionForPeerPullCredit(
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
- // Old transactions don't have it!
- timestamp: pullCredit.mergeTimestamp ?? TalerPreciseTimestamp.now(),
+ timestamp: timestampPreciseFromDb(pullCredit.mergeTimestamp),
info: {
expiration: peerContractTerms.purse_expiration,
summary: peerContractTerms.summary,
@@ -575,8 +579,7 @@ function buildTransactionForPeerPullCredit(
amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective),
amountRaw: Amounts.stringify(peerContractTerms.amount),
exchangeBaseUrl: pullCredit.exchangeBaseUrl,
- // Old transactions don't have it!
- timestamp: pullCredit.mergeTimestamp ?? TalerProtocolTimestamp.now(),
+ timestamp: timestampPreciseFromDb(pullCredit.mergeTimestamp),
info: {
expiration: peerContractTerms.purse_expiration,
summary: peerContractTerms.summary,
@@ -617,7 +620,7 @@ function buildTransactionForPeerPushCredit(
expiration: peerContractTerms.purse_expiration,
summary: peerContractTerms.summary,
},
- timestamp: wsr.timestampStart,
+ timestamp: timestampPreciseFromDb(wsr.timestampStart),
transactionId: constructTransactionIdentifier({
tag: TransactionType.PeerPushCredit,
peerPushCreditId: pushInc.peerPushCreditId,
@@ -640,7 +643,7 @@ function buildTransactionForPeerPushCredit(
summary: peerContractTerms.summary,
},
kycUrl: pushInc.kycUrl,
- timestamp: pushInc.timestamp,
+ timestamp: timestampPreciseFromDb(pushInc.timestamp),
transactionId: constructTransactionIdentifier({
tag: TransactionType.PeerPushCredit,
peerPushCreditId: pushInc.peerPushCreditId,
@@ -673,7 +676,7 @@ function buildTransactionForBankIntegratedWithdraw(
},
kycUrl: wgRecord.kycUrl,
exchangeBaseUrl: wgRecord.exchangeBaseUrl,
- timestamp: wgRecord.timestampStart,
+ timestamp: timestampPreciseFromDb(wgRecord.timestampStart),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Withdrawal,
withdrawalGroupId: wgRecord.withdrawalGroupId,
@@ -717,7 +720,7 @@ function buildTransactionForManualWithdraw(
},
kycUrl: withdrawalGroup.kycUrl,
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
- timestamp: withdrawalGroup.timestampStart,
+ timestamp: timestampPreciseFromDb(withdrawalGroup.timestampStart),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Withdrawal,
withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
@@ -748,7 +751,7 @@ function buildTransactionForRefund(
tag: TransactionType.Payment,
proposalId: refundRecord.proposalId,
}),
- timestamp: refundRecord.timestampCreated,
+ timestamp: timestampPreciseFromDb(refundRecord.timestampCreated),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Refund,
refundGroupId: refundRecord.refundGroupId,
@@ -786,7 +789,7 @@ function buildTransactionForRefresh(
refreshOutputAmount: Amounts.stringify(outputAmount),
originatingTransactionId:
refreshGroupRecord.reasonDetails?.originatingTransactionId,
- timestamp: refreshGroupRecord.timestampCreated,
+ timestamp: timestampPreciseFromDb(refreshGroupRecord.timestampCreated),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Refresh,
refreshGroupId: refreshGroupRecord.refreshGroupId,
@@ -812,7 +815,7 @@ function buildTransactionForDeposit(
txActions: computeDepositTransactionActions(dg),
amountRaw: Amounts.stringify(dg.counterpartyEffectiveDepositAmount),
amountEffective: Amounts.stringify(dg.totalPayCost),
- timestamp: dg.timestampCreated,
+ timestamp: timestampPreciseFromDb(dg.timestampCreated),
targetPaytoUri: dg.wire.payto_uri,
wireTransferDeadline: dg.wireTransferDeadline,
transactionId: constructTransactionIdentifier({
@@ -845,7 +848,7 @@ function buildTransactionForTip(
txActions: computeTipTransactionActions(tipRecord),
amountEffective: Amounts.stringify(tipRecord.rewardAmountEffective),
amountRaw: Amounts.stringify(tipRecord.rewardAmountRaw),
- timestamp: tipRecord.acceptedTimestamp,
+ timestamp: timestampPreciseFromDb(tipRecord.acceptedTimestamp),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Reward,
walletRewardId: tipRecord.walletRewardId,
@@ -922,7 +925,7 @@ async function buildTransactionForPurchase(
: Amounts.stringify(purchaseRecord.refundAmountAwaiting),
refunds,
posConfirmation: purchaseRecord.posConfirmation,
- timestamp,
+ timestamp: timestampPreciseFromDb(timestamp),
transactionId: constructTransactionIdentifier({
tag: TransactionType.Payment,
proposalId: purchaseRecord.proposalId,
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 32e63f4f6..fb503d75f 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -131,6 +131,7 @@ import {
ExchangeEntryDbUpdateStatus,
PendingTaskType,
isWithdrawableDenom,
+ timestampPreciseToDb,
} from "../index.js";
import {
TransitionInfo,
@@ -1325,7 +1326,7 @@ async function processWithdrawalGroupAbortingBank(
}
const txStatusOld = computeWithdrawalTransactionStatus(wg);
wg.status = WithdrawalGroupStatus.AbortedBank;
- wg.timestampFinish = TalerPreciseTimestamp.now();
+ wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now());
const txStatusNew = computeWithdrawalTransactionStatus(wg);
await tx.withdrawalGroups.put(wg);
return {
@@ -1458,7 +1459,7 @@ async function processWithdrawalGroupPendingReady(
}
const txStatusOld = computeWithdrawalTransactionStatus(wg);
wg.status = WithdrawalGroupStatus.Done;
- wg.timestampFinish = TalerPreciseTimestamp.now();
+ wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now());
const txStatusNew = computeWithdrawalTransactionStatus(wg);
await tx.withdrawalGroups.put(wg);
return {
@@ -1554,7 +1555,7 @@ async function processWithdrawalGroupPendingReady(
const oldTxState = computeWithdrawalTransactionStatus(wg);
logger.info(`now withdrawn ${numFinished} of ${numTotalCoins} coins`);
if (wg.timestampFinish === undefined && numFinished === numTotalCoins) {
- wg.timestampFinish = TalerPreciseTimestamp.now();
+ wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now());
wg.status = WithdrawalGroupStatus.Done;
await makeCoinsVisible(ws, tx, transactionId);
}
@@ -2047,8 +2048,9 @@ async function registerReserveWithBank(
if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
throw Error("invariant failed");
}
- r.wgInfo.bankInfo.timestampReserveInfoPosted =
- AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
+ r.wgInfo.bankInfo.timestampReserveInfoPosted = timestampPreciseToDb(
+ AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()),
+ );
const oldTxState = computeWithdrawalTransactionStatus(r);
r.status = WithdrawalGroupStatus.PendingWaitConfirmBank;
const newTxState = computeWithdrawalTransactionStatus(r);
@@ -2130,7 +2132,7 @@ async function processReserveBankStatus(
}
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
const oldTxState = computeWithdrawalTransactionStatus(r);
- r.wgInfo.bankInfo.timestampBankConfirmed = now;
+ r.wgInfo.bankInfo.timestampBankConfirmed = timestampPreciseToDb(now);
r.status = WithdrawalGroupStatus.FailedBankAborted;
const newTxState = computeWithdrawalTransactionStatus(r);
await tx.withdrawalGroups.put(r);
@@ -2179,7 +2181,7 @@ async function processReserveBankStatus(
if (status.transfer_done) {
logger.info("withdrawal: transfer confirmed by bank.");
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
- r.wgInfo.bankInfo.timestampBankConfirmed = now;
+ r.wgInfo.bankInfo.timestampBankConfirmed = timestampPreciseToDb(now);
r.status = WithdrawalGroupStatus.PendingQueryingStatus;
} else {
logger.info("withdrawal: transfer not yet confirmed by bank");
@@ -2285,7 +2287,7 @@ export async function internalPrepareCreateWithdrawalGroup(
denomsSel: initialDenomSel,
exchangeBaseUrl: canonExchange,
instructedAmount: Amounts.stringify(amount),
- timestampStart: now,
+ timestampStart: timestampPreciseToDb(now),
rawWithdrawalAmount: initialDenomSel.totalWithdrawCost,
effectiveWithdrawalAmount: initialDenomSel.totalCoinValue,
secretSeed,
@@ -2339,8 +2341,7 @@ export async function internalPerformCreateWithdrawalGroup(
if (!prep.creationInfo) {
return { withdrawalGroup, transitionInfo: undefined };
}
- const { amount, canonExchange, exchangeDetails } =
- prep.creationInfo;
+ const { amount, canonExchange, exchangeDetails } = prep.creationInfo;
await tx.withdrawalGroups.add(withdrawalGroup);
await tx.reserves.put({
@@ -2350,7 +2351,7 @@ export async function internalPerformCreateWithdrawalGroup(
const exchange = await tx.exchanges.get(withdrawalGroup.exchangeBaseUrl);
if (exchange) {
- exchange.lastWithdrawal = TalerPreciseTimestamp.now();
+ exchange.lastWithdrawal = timestampPreciseToDb(TalerPreciseTimestamp.now());
exchange.entryStatus = ExchangeEntryDbRecordStatus.Used;
await tx.exchanges.put(exchange);
}
@@ -2541,11 +2542,7 @@ export async function createManualWithdrawal(
});
const exchangePaytoUris = await ws.db
- .mktx((x) => [
- x.withdrawalGroups,
- x.exchanges,
- x.exchangeDetails,
- ])
+ .mktx((x) => [x.withdrawalGroups, x.exchanges, x.exchangeDetails])
.runReadOnly(async (tx) => {
return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId);
});