taler-util,wallet-core: implement TalerPreciseTimestamp

Fixes #7703
This commit is contained in:
Florian Dold 2023-05-26 12:19:32 +02:00
parent 557dcec30d
commit cd8f76db61
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
44 changed files with 274 additions and 208 deletions

View File

@ -1473,7 +1473,7 @@ async function updateUploadFees(
x,
).amount;
};
const expirationTime = AbsoluteTime.fromTimestamp(expiration);
const expirationTime = AbsoluteTime.fromProtocolTimestamp(expiration);
const years = Duration.toIntegerYears(Duration.getRemaining(expirationTime));
logger.info(`computing fees for ${years} years`);
// For now, we compute fees for *all* available providers.

View File

@ -59,7 +59,7 @@ export async function runAgeRestrictionsPeerTest(t: GlobalTestState) {
restrictAge: 13,
});
const purse_expiration = AbsoluteTime.toTimestamp(
const purse_expiration = AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
Duration.fromSpec({ days: 2 }),

View File

@ -177,7 +177,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
return {
denomPub: x.denom_pub,
expireDeposit: AbsoluteTime.stringify(
AbsoluteTime.fromTimestamp(x.stamp_expire_deposit),
AbsoluteTime.fromProtocolTimestamp(x.stamp_expire_deposit),
),
};
});
@ -186,7 +186,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
return {
denomPub: x.denom_pub,
expireDeposit: AbsoluteTime.stringify(
AbsoluteTime.fromTimestamp(x.stamp_expire_deposit),
AbsoluteTime.fromProtocolTimestamp(x.stamp_expire_deposit),
),
};
});
@ -196,7 +196,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
console.log(
"list issue date",
AbsoluteTime.stringify(AbsoluteTime.fromTimestamp(keys1.list_issue_date)),
AbsoluteTime.stringify(AbsoluteTime.fromProtocolTimestamp(keys1.list_issue_date)),
);
console.log("num denoms", keys1.denoms.length);
console.log("denoms", JSON.stringify(denomPubs1, undefined, 2));
@ -205,7 +205,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
console.log(
"list issue date",
AbsoluteTime.stringify(AbsoluteTime.fromTimestamp(keys2.list_issue_date)),
AbsoluteTime.stringify(AbsoluteTime.fromProtocolTimestamp(keys2.list_issue_date)),
);
console.log("num denoms", keys2.denoms.length);
console.log("denoms", JSON.stringify(denomPubs2, undefined, 2));
@ -227,7 +227,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
);
console.log(
`the new /keys response was issued ${AbsoluteTime.stringify(
AbsoluteTime.fromTimestamp(keys2.list_issue_date),
AbsoluteTime.fromProtocolTimestamp(keys2.list_issue_date),
)}`,
);
console.log(

View File

@ -275,7 +275,7 @@ export async function runLibeufinBasicTest(t: GlobalTestState) {
summary: "Buy me!",
amount: "EUR:5",
fulfillment_url: "taler://fulfillment-success/thx",
wire_transfer_deadline: AbsoluteTime.toTimestamp(AbsoluteTime.now()),
wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now()),
};
await makeTestPayment(t, { wallet, merchant, order });

View File

@ -75,7 +75,7 @@ export async function runPeerToPeerPullTest(t: GlobalTestState) {
await withdrawalDoneCond;
const purse_expiration = AbsoluteTime.toTimestamp(
const purse_expiration = AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
Duration.fromSpec({ days: 2 }),

View File

@ -47,7 +47,7 @@ export async function runPeerToPeerPushTest(t: GlobalTestState) {
await wallet1.runUntilDone();
const purse_expiration = AbsoluteTime.toTimestamp(
const purse_expiration = AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
Duration.fromSpec({ days: 2 }),

View File

@ -50,7 +50,7 @@ export async function runRefundGoneTest(t: GlobalTestState) {
summary: "Buy me!",
amount: "TESTKUDOS:5",
fulfillment_url: "taler://fulfillment-success/thx",
pay_deadline: AbsoluteTime.toTimestamp(
pay_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
durationFromSpec({

View File

@ -63,7 +63,7 @@
* Imports.
*/
import { DenominationPubKey, UnblindedSignature } from "./taler-types.js";
import { TalerProtocolDuration, TalerProtocolTimestamp } from "./time.js";
import { TalerProtocolDuration, TalerProtocolTimestamp, TalerPreciseTimestamp } from "./time.js";
export const BACKUP_TAG = "gnu-taler-wallet-backup-content" as const;
/**
@ -148,7 +148,7 @@ export interface WalletBackupContentV1 {
* This timestamp should only be advanced if the content
* of the backup changes.
*/
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
/**
* Per-exchange data sorted by exchange master public key.
@ -274,14 +274,14 @@ export type BackupWgInfo =
*
* Set to undefined if that hasn't happened yet.
*/
timestamp_reserve_info_posted?: TalerProtocolTimestamp;
timestamp_reserve_info_posted?: TalerPreciseTimestamp;
/**
* Time when the reserve was confirmed by the bank.
*
* Set to undefined if not confirmed yet.
*/
timestamp_bank_confirmed?: TalerProtocolTimestamp;
timestamp_bank_confirmed?: TalerPreciseTimestamp;
}
| {
type: BackupWgType.PeerPullCredit;
@ -315,9 +315,9 @@ export interface BackupWithdrawalGroup {
exchange_base_url: string;
timestamp_created: TalerProtocolTimestamp;
timestamp_created: TalerPreciseTimestamp;
timestamp_finish?: TalerProtocolTimestamp;
timestamp_finish?: TalerPreciseTimestamp;
operation_status: BackupOperationStatus;
@ -473,9 +473,9 @@ export interface BackupRecoupGroup {
/**
* Timestamp when the recoup was started.
*/
timestamp_created: TalerProtocolTimestamp;
timestamp_created: TalerPreciseTimestamp;
timestamp_finish?: TalerProtocolTimestamp;
timestamp_finish?: TalerPreciseTimestamp;
finish_clock?: TalerProtocolTimestamp;
// FIXME: Use some enum here!
finish_is_failure?: boolean;
@ -633,14 +633,14 @@ export interface BackupTip {
* Has the user accepted the tip? Only after the tip has been accepted coins
* withdrawn from the tip may be used.
*/
timestamp_accepted: TalerProtocolTimestamp | undefined;
timestamp_accepted: TalerPreciseTimestamp | undefined;
/**
* When was the tip first scanned by the wallet?
*/
timestamp_created: TalerProtocolTimestamp;
timestamp_created: TalerPreciseTimestamp;
timestamp_finished?: TalerProtocolTimestamp;
timestamp_finished?: TalerPreciseTimestamp;
finish_is_failure?: boolean;
/**
@ -765,9 +765,9 @@ export interface BackupRefreshGroup {
*/
old_coins: BackupRefreshOldCoin[];
timestamp_created: TalerProtocolTimestamp;
timestamp_created: TalerPreciseTimestamp;
timestamp_finish?: TalerProtocolTimestamp;
timestamp_finish?: TalerPreciseTimestamp;
finish_is_failure?: boolean;
}
@ -940,7 +940,7 @@ export interface BackupPurchase {
* Timestamp of the first time that sending a payment to the merchant
* for this purchase was successful.
*/
timestamp_first_successful_pay: TalerProtocolTimestamp | undefined;
timestamp_first_successful_pay: TalerPreciseTimestamp | undefined;
/**
* Signature by the merchant confirming the payment.
@ -952,13 +952,13 @@ export interface BackupPurchase {
*/
pos_confirmation: string | undefined;
timestamp_proposed: TalerProtocolTimestamp;
timestamp_proposed: TalerPreciseTimestamp;
/**
* When was the purchase made?
* Refers to the time that the user accepted.
*/
timestamp_accepted: TalerProtocolTimestamp | undefined;
timestamp_accepted: TalerPreciseTimestamp | undefined;
/**
* Pending refunds for the purchase. A refund is pending
@ -1186,7 +1186,7 @@ export interface BackupExchange {
*
* Used to facilitate automatic merging.
*/
update_clock: TalerProtocolTimestamp;
update_clock: TalerPreciseTimestamp;
}
/**
@ -1258,7 +1258,7 @@ export interface BackupExchangeDetails {
/**
* Timestamp when the ToS has been accepted.
*/
tos_accepted_timestamp: TalerProtocolTimestamp | undefined;
tos_accepted_timestamp: TalerPreciseTimestamp | undefined;
}
export enum BackupProposalStatus {

View File

@ -25,8 +25,9 @@ import { Codec, renderContext, Context } from "./codec.js";
declare const flavor_AbsoluteTime: unique symbol;
declare const flavor_TalerProtocolTimestamp: unique symbol;
declare const flavor_TalerWalletDbTimestamp: unique symbol;
declare const flavor_TalerPreciseTimestamp: unique symbol;
// FIXME: Make this opaque!
export interface AbsoluteTime {
/**
* Timestamp in milliseconds.
@ -45,7 +46,7 @@ export interface TalerProtocolTimestamp {
readonly _flavor?: typeof flavor_TalerProtocolTimestamp;
}
export interface TalerWalletDbTimestamp {
export interface TalerPreciseTimestamp {
/**
* Seconds (as integer) since epoch.
*/
@ -56,12 +57,32 @@ export interface TalerWalletDbTimestamp {
*/
readonly off_us?: number;
readonly _flavor?: typeof flavor_TalerWalletDbTimestamp;
readonly _flavor?: typeof flavor_TalerPreciseTimestamp;
}
export namespace TalerPreciseTimestamp {
export function now(): TalerPreciseTimestamp {
const absNow = AbsoluteTime.now();
return AbsoluteTime.toPreciseTimestamp(absNow);
}
export function round(t: TalerPreciseTimestamp): TalerProtocolTimestamp {
return {
t_s: t.t_s,
}
}
export function fromSeconds(s: number): TalerPreciseTimestamp {
return {
t_s: Math.floor(s),
off_us: (s - Math.floor(s)) / 1000 / 1000,
};
}
}
export namespace TalerProtocolTimestamp {
export function now(): TalerProtocolTimestamp {
return AbsoluteTime.toTimestamp(AbsoluteTime.now());
return AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now());
}
export function zero(): TalerProtocolTimestamp {
@ -81,6 +102,7 @@ export namespace TalerProtocolTimestamp {
t_s: s,
};
}
export function min(
t1: TalerProtocolTimestamp,
t2: TalerProtocolTimestamp,
@ -309,7 +331,7 @@ export namespace AbsoluteTime {
return cmp(t, now()) <= 0;
}
export function fromTimestamp(t: TalerProtocolTimestamp): AbsoluteTime {
export function fromProtocolTimestamp(t: TalerProtocolTimestamp): AbsoluteTime {
if (t.t_s === "never") {
return { t_ms: "never" };
}
@ -318,7 +340,31 @@ export namespace AbsoluteTime {
};
}
export function toTimestamp(at: AbsoluteTime): TalerProtocolTimestamp {
export function fromPreciseTimestamp(t: TalerPreciseTimestamp): AbsoluteTime {
if (t.t_s === "never") {
return { t_ms: "never" };
}
const offsetUs = t.off_us ?? 0;
return {
t_ms: t.t_s * 1000 + offsetUs / 1000,
};
}
export function toPreciseTimestamp(at: AbsoluteTime): TalerPreciseTimestamp {
if (at.t_ms == "never") {
return {
t_s: "never",
};
}
const t_s = Math.floor(at.t_ms / 1000);
const off_us = Math.floor(1000 * (at.t_ms - t_s * 1000));
return {
t_s,
off_us,
}
}
export function toProtocolTimestamp(at: AbsoluteTime): TalerProtocolTimestamp {
if (at.t_ms === "never") {
return { t_s: "never" };
}

View File

@ -24,7 +24,7 @@
/**
* Imports.
*/
import { TalerProtocolTimestamp } from "./time.js";
import { TalerPreciseTimestamp, TalerProtocolTimestamp } from "./time.js";
import {
AmountString,
Product,
@ -141,7 +141,7 @@ export interface TransactionCommon {
type: TransactionType;
// main timestamp of the transaction
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
/**
* Transaction state, as per DD37.

View File

@ -1112,7 +1112,7 @@ peerCli
partialContractTerms: {
amount: args.initiatePayPull.amount,
summary: args.initiatePayPull.summary ?? "Invoice",
purse_expiration: AbsoluteTime.toTimestamp(purseExpiration),
purse_expiration: AbsoluteTime.toProtocolTimestamp(purseExpiration),
},
},
);
@ -1168,7 +1168,7 @@ peerCli
partialContractTerms: {
amount: args.payPush.amount,
summary: args.payPush.summary ?? "Payment",
purse_expiration: AbsoluteTime.toTimestamp(purseExpiration),
purse_expiration: AbsoluteTime.toProtocolTimestamp(purseExpiration),
},
},
);

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import { AbsoluteTime } from "@gnu-taler/taler-util";
import { AbsoluteTime, TalerErrorCode } from "@gnu-taler/taler-util";
import test from "ava";
import { CryptoDispatcher, CryptoWorkerFactory } from "./crypto-dispatcher.js";
import {
@ -72,7 +72,7 @@ export class MyCryptoWorker implements CryptoWorker {
id: msg.id,
type: "error",
error: {
code: 42,
code: TalerErrorCode.ANASTASIS_EMAIL_INVALID,
when: AbsoluteTime.now(),
hint: "bla",
},

View File

@ -57,6 +57,7 @@ import {
AttentionInfo,
Logger,
CoinPublicKeyString,
TalerPreciseTimestamp,
} from "@gnu-taler/taler-util";
import {
DbAccess,
@ -236,14 +237,14 @@ export interface ReserveBankInfo {
*
* Set to undefined if that hasn't happened yet.
*/
timestampReserveInfoPosted: TalerProtocolTimestamp | undefined;
timestampReserveInfoPosted: TalerPreciseTimestamp | undefined;
/**
* Time when the reserve was confirmed by the bank.
*
* Set to undefined if not confirmed yet.
*/
timestampBankConfirmed: TalerProtocolTimestamp | undefined;
timestampBankConfirmed: TalerPreciseTimestamp | undefined;
}
/**
@ -516,7 +517,7 @@ export interface ExchangeDetailsRecord {
tosAccepted:
| {
etag: string;
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
}
| undefined;
@ -556,7 +557,7 @@ export interface ExchangeDetailsPointer {
* Timestamp when the (masterPublicKey, currency) pointer
* has been updated.
*/
updateClock: TalerProtocolTimestamp;
updateClock: TalerPreciseTimestamp;
}
/**
@ -573,7 +574,7 @@ export interface ExchangeRecord {
*
* Used mostly in the UI to suggest exchanges.
*/
lastWithdrawal?: TalerProtocolTimestamp;
lastWithdrawal?: TalerPreciseTimestamp;
/**
* Pointer to the current exchange details.
@ -595,14 +596,14 @@ export interface ExchangeRecord {
/**
* Last time when the exchange was updated (both /keys and /wire).
*/
lastUpdate: TalerProtocolTimestamp | undefined;
lastUpdate: TalerPreciseTimestamp | undefined;
/**
* Next scheduled update for the exchange.
*
* (This field must always be present, so we can index on the timestamp.)
*/
nextUpdate: TalerProtocolTimestamp;
nextUpdate: TalerPreciseTimestamp;
lastKeysEtag: string | undefined;
@ -614,7 +615,7 @@ export interface ExchangeRecord {
* Updated whenever the exchange's denominations are updated or when
* the refresh check has been done.
*/
nextRefreshCheck: TalerProtocolTimestamp;
nextRefreshCheck: TalerPreciseTimestamp;
/**
* Public key of the reserve that we're currently using for
@ -803,7 +804,7 @@ export interface TipRecord {
* Has the user accepted the tip? Only after the tip has been accepted coins
* withdrawn from the tip may be used.
*/
acceptedTimestamp: TalerProtocolTimestamp | undefined;
acceptedTimestamp: TalerPreciseTimestamp | undefined;
/**
* The tipped amount.
@ -856,7 +857,7 @@ export interface TipRecord {
*/
merchantTipId: string;
createdTimestamp: TalerProtocolTimestamp;
createdTimestamp: TalerPreciseTimestamp;
/**
* The url to be redirected after the tip is accepted.
@ -866,7 +867,7 @@ export interface TipRecord {
* Timestamp for when the wallet finished picking up the tip
* from the merchant.
*/
pickedUpTimestamp: TalerProtocolTimestamp | undefined;
pickedUpTimestamp: TalerPreciseTimestamp | undefined;
}
export enum RefreshCoinStatus {
@ -974,12 +975,12 @@ export interface RefreshGroupRecord {
*/
statusPerCoin: RefreshCoinStatus[];
timestampCreated: TalerProtocolTimestamp;
timestampCreated: TalerPreciseTimestamp;
/**
* Timestamp when the refresh session finished.
*/
timestampFinished: TalerProtocolTimestamp | undefined;
timestampFinished: TalerPreciseTimestamp | undefined;
}
/**
@ -1233,7 +1234,7 @@ export interface PurchaseRecord {
* Timestamp of the first time that sending a payment to the merchant
* for this purchase was successful.
*/
timestampFirstSuccessfulPay: TalerProtocolTimestamp | undefined;
timestampFirstSuccessfulPay: TalerPreciseTimestamp | undefined;
merchantPaySig: string | undefined;
@ -1242,13 +1243,13 @@ export interface PurchaseRecord {
/**
* When was the purchase record created?
*/
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
/**
* When was the purchase made?
* Refers to the time that the user accepted.
*/
timestampAccept: TalerProtocolTimestamp | undefined;
timestampAccept: TalerPreciseTimestamp | undefined;
/**
* Pending refunds for the purchase. A refund is pending
@ -1262,7 +1263,7 @@ export interface PurchaseRecord {
* When was the last refund made?
* Set to 0 if no refund was made on the purchase.
*/
timestampLastRefundStatus: TalerProtocolTimestamp | undefined;
timestampLastRefundStatus: TalerPreciseTimestamp | undefined;
/**
* Last session signature that we submitted to /pay (if any).
@ -1312,12 +1313,12 @@ export interface WalletBackupConfState {
/**
* Timestamp stored in the last backup.
*/
lastBackupTimestamp?: TalerProtocolTimestamp;
lastBackupTimestamp?: TalerPreciseTimestamp;
/**
* Last time we tried to do a backup.
*/
lastBackupCheckTimestamp?: TalerProtocolTimestamp;
lastBackupCheckTimestamp?: TalerPreciseTimestamp;
lastBackupNonce?: string;
}
@ -1421,12 +1422,12 @@ export interface WithdrawalGroupRecord {
* When was the withdrawal operation started started?
* Timestamp in milliseconds.
*/
timestampStart: TalerProtocolTimestamp;
timestampStart: TalerPreciseTimestamp;
/**
* When was the withdrawal operation completed?
*/
timestampFinish?: TalerProtocolTimestamp;
timestampFinish?: TalerPreciseTimestamp;
/**
* Current status of the reserve.
@ -1517,9 +1518,9 @@ export interface RecoupGroupRecord {
exchangeBaseUrl: string;
timestampStarted: TalerProtocolTimestamp;
timestampStarted: TalerPreciseTimestamp;
timestampFinished: TalerProtocolTimestamp | undefined;
timestampFinished: TalerPreciseTimestamp | undefined;
/**
* Public keys that identify the coins being recouped
@ -1553,7 +1554,7 @@ export type BackupProviderState =
}
| {
tag: BackupProviderStateTag.Ready;
nextBackupTimestamp: TalerProtocolTimestamp;
nextBackupTimestamp: TalerPreciseTimestamp;
}
| {
tag: BackupProviderStateTag.Retrying;
@ -1598,7 +1599,7 @@ export interface BackupProviderRecord {
* Does NOT correspond to the timestamp of the backup,
* which only changes when the backup content changes.
*/
lastBackupCycleTimestamp?: TalerProtocolTimestamp;
lastBackupCycleTimestamp?: TalerPreciseTimestamp;
/**
* Proposal that we're currently trying to pay for.
@ -1693,9 +1694,9 @@ export interface DepositGroupRecord {
*/
effectiveDepositAmount: AmountString;
timestampCreated: TalerProtocolTimestamp;
timestampCreated: TalerPreciseTimestamp;
timestampFinished: TalerProtocolTimestamp | undefined;
timestampFinished: TalerPreciseTimestamp | undefined;
operationStatus: DepositOperationStatus;
@ -1728,7 +1729,7 @@ export interface GhostDepositGroupRecord {
* When multiple deposits for the same contract terms hash
* have a different timestamp, we choose the earliest one.
*/
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
contractTermsHash: string;
@ -1821,7 +1822,7 @@ export interface PeerPushPaymentInitiationRecord {
purseExpiration: TalerProtocolTimestamp;
timestampCreated: TalerProtocolTimestamp;
timestampCreated: TalerPreciseTimestamp;
/**
* Status of the peer push payment initiation.
@ -1882,7 +1883,7 @@ export interface PeerPullPaymentInitiationRecord {
contractTerms: PeerContractTerms;
mergeTimestamp: TalerProtocolTimestamp;
mergeTimestamp: TalerPreciseTimestamp;
mergeReserveRowId: number;
@ -1924,7 +1925,7 @@ export interface PeerPushPaymentIncomingRecord {
contractPriv: string;
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
estimatedAmountEffective: AmountString;
@ -1984,7 +1985,7 @@ export interface PeerPullPaymentIncomingRecord {
contractTerms: PeerContractTerms;
timestampCreated: TalerProtocolTimestamp;
timestampCreated: TalerPreciseTimestamp;
/**
* Contract priv that we got from the other party.
@ -2081,7 +2082,7 @@ export interface UserAttentionRecord {
/**
* When the user mark this notification as read.
*/
read: TalerProtocolTimestamp | undefined;
read: TalerPreciseTimestamp | undefined;
}
export interface DbExchangeHandle {
@ -2125,7 +2126,7 @@ export interface RefundGroupRecord {
/**
* Timestamp when the refund group was created.
*/
timestampCreated: TalerProtocolTimestamp;
timestampCreated: TalerPreciseTimestamp;
proposalId: string;
@ -2180,7 +2181,7 @@ export interface RefundItemRecord {
/**
* Time when the wallet became aware of the refund.
*/
obtainedTime: TalerProtocolTimestamp;
obtainedTime: TalerPreciseTimestamp;
refundAmount: AmountString;

View File

@ -256,7 +256,7 @@ export async function depositCoin(args: {
const depositPayto =
args.depositPayto ?? "payto://x-taler-bank/localhost/foo";
const wireSalt = args.wireSalt ?? encodeCrock(getRandomBytes(16));
const timestampNow = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const timestampNow = AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now());
const contractTermsHash =
args.contractTermsHash ?? encodeCrock(getRandomBytes(64));
const depositTimestamp = timestampNow;

View File

@ -22,6 +22,7 @@ import {
AttentionInfo,
Logger,
TalerProtocolTimestamp,
TalerPreciseTimestamp,
UserAttentionByIdRequest,
UserAttentionPriority,
UserAttentionsCountResponse,
@ -95,7 +96,7 @@ export async function markAttentionRequestAsRead(
if (!ua) throw Error("attention request not found");
tx.userAttention.put({
...ua,
read: TalerProtocolTimestamp.now(),
read: TalerPreciseTimestamp.now(),
});
});
}

View File

@ -62,6 +62,7 @@ import {
Logger,
stringToBytes,
WalletBackupContentV1,
TalerPreciseTimestamp,
} from "@gnu-taler/taler-util";
import {
CoinSourceType,
@ -521,7 +522,7 @@ export async function exportBackup(
});
});
const ts = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const ts = TalerPreciseTimestamp.now();
if (!bs.lastBackupTimestamp) {
bs.lastBackupTimestamp = ts;
@ -565,7 +566,7 @@ export async function exportBackup(
bs.lastBackupNonce = encodeCrock(getRandomBytes(32));
logger.trace(
`setting timestamp to ${AbsoluteTime.toIsoString(
AbsoluteTime.fromTimestamp(ts),
AbsoluteTime.fromPreciseTimestamp(ts),
)} and nonce to ${bs.lastBackupNonce}`,
);
await tx.config.put({

View File

@ -35,6 +35,7 @@ import {
PayCoinSelection,
RefreshReason,
TalerProtocolTimestamp,
TalerPreciseTimestamp,
WalletBackupContentV1,
WireInfo,
} from "@gnu-taler/taler-util";
@ -349,8 +350,8 @@ export async function importBackup(
},
permanent: true,
lastUpdate: undefined,
nextUpdate: TalerProtocolTimestamp.now(),
nextRefreshCheck: TalerProtocolTimestamp.now(),
nextUpdate: TalerPreciseTimestamp.now(),
nextRefreshCheck: TalerPreciseTimestamp.now(),
lastKeysEtag: undefined,
lastWireEtag: undefined,
});

View File

@ -71,6 +71,7 @@ import {
TalerErrorCode,
TalerErrorDetail,
TalerProtocolTimestamp,
TalerPreciseTimestamp,
URL,
WalletBackupContentV1,
} from "@gnu-taler/taler-util";
@ -246,9 +247,9 @@ interface BackupForProviderArgs {
backupProviderBaseUrl: string;
}
function getNextBackupTimestamp(): TalerProtocolTimestamp {
function getNextBackupTimestamp(): TalerPreciseTimestamp {
// FIXME: Randomize!
return AbsoluteTime.toTimestamp(
return AbsoluteTime.toPreciseTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
durationFromSpec({ minutes: 5 }),
@ -329,7 +330,7 @@ async function runBackupCycleForProvider(
if (!prov) {
return;
}
prov.lastBackupCycleTimestamp = TalerProtocolTimestamp.now();
prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now();
prov.state = {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: getNextBackupTimestamp(),
@ -442,7 +443,7 @@ async function runBackupCycleForProvider(
return;
}
prov.lastBackupHash = encodeCrock(currentBackupHash);
prov.lastBackupCycleTimestamp = TalerProtocolTimestamp.now();
prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now();
prov.state = {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: getNextBackupTimestamp(),
@ -676,7 +677,7 @@ export async function addBackupProvider(
if (req.activate) {
oldProv.state = {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: TalerProtocolTimestamp.now(),
nextBackupTimestamp: TalerPreciseTimestamp.now(),
};
logger.info("setting existing backup provider to active");
await tx.backupProviders.put(oldProv);
@ -698,7 +699,7 @@ export async function addBackupProvider(
if (req.activate) {
state = {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: TalerProtocolTimestamp.now(),
nextBackupTimestamp: TalerPreciseTimestamp.now(),
};
} else {
state = {
@ -773,8 +774,8 @@ export interface ProviderInfo {
* Last communication issue with the provider.
*/
lastError?: TalerErrorDetail;
lastSuccessfulBackupTimestamp?: TalerProtocolTimestamp;
lastAttemptedBackupTimestamp?: TalerProtocolTimestamp;
lastSuccessfulBackupTimestamp?: TalerPreciseTimestamp;
lastAttemptedBackupTimestamp?: TalerPreciseTimestamp;
paymentProposalIds: string[];
backupProblem?: BackupProblem;
paymentStatus: ProviderPaymentStatus;
@ -894,7 +895,7 @@ async function getProviderPaymentInfo(
return {
type: ProviderPaymentType.Paid,
paidUntil: AbsoluteTime.addDuration(
AbsoluteTime.fromTimestamp(status.contractTerms.timestamp),
AbsoluteTime.fromProtocolTimestamp(status.contractTerms.timestamp),
durationFromSpec({ years: 1 }), //FIXME: take this from the contract term
),
};
@ -1010,7 +1011,7 @@ async function backupRecoveryTheirs(
shouldRetryFreshProposal: false,
state: {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: TalerProtocolTimestamp.now(),
nextBackupTimestamp: TalerPreciseTimestamp.now(),
},
uids: [encodeCrock(getRandomBytes(32))],
});

View File

@ -51,6 +51,7 @@ import {
stringToBytes,
TalerErrorCode,
TalerProtocolTimestamp,
TalerPreciseTimestamp,
TrackTransaction,
TransactionMajorState,
TransactionMinorState,
@ -779,7 +780,7 @@ export async function processDepositGroup(
}
}
if (allDepositedAndWired) {
dg.timestampFinished = TalerProtocolTimestamp.now();
dg.timestampFinished = TalerPreciseTimestamp.now();
dg.operationStatus = DepositOperationStatus.Finished;
await tx.depositGroups.put(dg);
}
@ -858,9 +859,9 @@ async function getExchangeWireFee(
}
const fee = fees.find((x) => {
return AbsoluteTime.isBetween(
AbsoluteTime.fromTimestamp(time),
AbsoluteTime.fromTimestamp(x.startStamp),
AbsoluteTime.fromTimestamp(x.endStamp),
AbsoluteTime.fromProtocolTimestamp(time),
AbsoluteTime.fromProtocolTimestamp(x.startStamp),
AbsoluteTime.fromProtocolTimestamp(x.endStamp),
);
});
if (!fee) {
@ -952,7 +953,7 @@ export async function prepareDepositGroup(
});
const now = AbsoluteTime.now();
const nowRounded = AbsoluteTime.toTimestamp(now);
const nowRounded = AbsoluteTime.toProtocolTimestamp(now);
const contractTerms: MerchantContractTerms = {
exchanges: exchangeInfos,
amount: req.amount,
@ -966,7 +967,7 @@ export async function prepareDepositGroup(
wire_transfer_deadline: nowRounded,
order_id: "",
h_wire: "",
pay_deadline: AbsoluteTime.toTimestamp(
pay_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(now, durationFromSpec({ hours: 1 })),
),
merchant: {
@ -1066,7 +1067,7 @@ export async function createDepositGroup(
});
const now = AbsoluteTime.now();
const nowRounded = AbsoluteTime.toTimestamp(now);
const nowRounded = AbsoluteTime.toProtocolTimestamp(now);
const noncePair = await ws.cryptoApi.createEddsaKeypair({});
const merchantPair = await ws.cryptoApi.createEddsaKeypair({});
const wireSalt = encodeCrock(getRandomBytes(16));
@ -1084,7 +1085,7 @@ export async function createDepositGroup(
wire_transfer_deadline: nowRounded,
order_id: "",
h_wire: wireHash,
pay_deadline: AbsoluteTime.toTimestamp(
pay_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(now, durationFromSpec({ hours: 1 })),
),
merchant: {
@ -1150,7 +1151,7 @@ export async function createDepositGroup(
depositGroupId,
noncePriv: noncePair.priv,
noncePub: noncePair.pub,
timestampCreated: AbsoluteTime.toTimestamp(now),
timestampCreated: AbsoluteTime.toPreciseTimestamp(now),
timestampFinished: undefined,
transactionPerCoin: payCoinSel.coinSel.coinPubs.map(
() => DepositElementStatus.Unknown,
@ -1260,8 +1261,8 @@ export async function getCounterpartyEffectiveDepositAmount(
const fee = exchangeDetails.wireInfo.feesForType[wireType].find((x) => {
return AbsoluteTime.isBetween(
AbsoluteTime.now(),
AbsoluteTime.fromTimestamp(x.startStamp),
AbsoluteTime.fromTimestamp(x.endStamp),
AbsoluteTime.fromProtocolTimestamp(x.startStamp),
AbsoluteTime.fromProtocolTimestamp(x.endStamp),
);
})?.wireFee;
if (fee) {
@ -1337,8 +1338,8 @@ export async function getTotalFeesForDepositAmount(
(x) => {
return AbsoluteTime.isBetween(
AbsoluteTime.now(),
AbsoluteTime.fromTimestamp(x.startStamp),
AbsoluteTime.fromTimestamp(x.endStamp),
AbsoluteTime.fromProtocolTimestamp(x.startStamp),
AbsoluteTime.fromProtocolTimestamp(x.endStamp),
);
},
)?.wireFee;

View File

@ -43,6 +43,7 @@ import {
Recoup,
TalerError,
TalerErrorCode,
TalerPreciseTimestamp,
TalerProtocolDuration,
TalerProtocolTimestamp,
URL,
@ -229,7 +230,7 @@ export async function acceptExchangeTermsOfService(
if (d) {
d.tosAccepted = {
etag: etag || d.tosCurrentEtag,
timestamp: TalerProtocolTimestamp.now(),
timestamp: TalerPreciseTimestamp.now(),
};
await tx.exchangeDetails.put(d);
}
@ -407,8 +408,8 @@ export async function provideExchangeRecordInTx(
baseUrl: baseUrl,
detailsPointer: undefined,
lastUpdate: undefined,
nextUpdate: AbsoluteTime.toTimestamp(now),
nextRefreshCheck: AbsoluteTime.toTimestamp(now),
nextUpdate: AbsoluteTime.toPreciseTimestamp(now),
nextRefreshCheck: AbsoluteTime.toPreciseTimestamp(now),
lastKeysEtag: undefined,
lastWireEtag: undefined,
};
@ -497,7 +498,7 @@ async function downloadExchangeKeysInfo(
protocolVersion: exchangeKeysJsonUnchecked.version,
signingKeys: exchangeKeysJsonUnchecked.signkeys,
reserveClosingDelay: exchangeKeysJsonUnchecked.reserve_closing_delay,
expiry: AbsoluteTime.toTimestamp(
expiry: AbsoluteTime.toProtocolTimestamp(
getExpiry(resp, {
minDuration: durationFromSpec({ hours: 1 }),
}),
@ -601,7 +602,9 @@ export async function updateExchangeFromUrlHandler(
if (
!forceNow &&
exchangeDetails !== undefined &&
!AbsoluteTime.isExpired(AbsoluteTime.fromTimestamp(exchange.nextUpdate))
!AbsoluteTime.isExpired(
AbsoluteTime.fromPreciseTimestamp(exchange.nextUpdate),
)
) {
logger.info("using existing exchange info");
return {
@ -724,15 +727,17 @@ export async function updateExchangeFromUrlHandler(
if (existingDetails?.rowId) {
newDetails.rowId = existingDetails.rowId;
}
r.lastUpdate = TalerProtocolTimestamp.now();
r.nextUpdate = keysInfo.expiry;
r.lastUpdate = TalerPreciseTimestamp.now();
r.nextUpdate = AbsoluteTime.toPreciseTimestamp(
AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry),
);
// New denominations might be available.
r.nextRefreshCheck = TalerProtocolTimestamp.now();
r.nextRefreshCheck = TalerPreciseTimestamp.now();
if (detailsPointerChanged) {
r.detailsPointer = {
currency: newDetails.currency,
masterPublicKey: newDetails.masterPublicKey,
updateClock: TalerProtocolTimestamp.now(),
updateClock: TalerPreciseTimestamp.now(),
};
}
await tx.exchanges.put(r);

View File

@ -66,6 +66,7 @@ import {
TalerError,
TalerErrorCode,
TalerErrorDetail,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
TalerProtocolViolationError,
TalerUriAction,
@ -621,7 +622,7 @@ async function createPurchase(
noncePriv: priv,
noncePub: pub,
claimToken,
timestamp: AbsoluteTime.toTimestamp(AbsoluteTime.now()),
timestamp: TalerPreciseTimestamp.now(),
merchantBaseUrl,
orderId,
proposalId: proposalId,
@ -682,7 +683,7 @@ async function storeFirstPaySuccess(
tag: TransactionType.Payment,
proposalId,
});
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
const transitionInfo = await ws.db
.mktx((x) => [x.purchases, x.contractTerms])
.runReadWrite(async (tx) => {
@ -721,7 +722,7 @@ async function storeFirstPaySuccess(
const ar = Duration.fromTalerProtocolDuration(protoAr);
logger.info("auto_refund present");
purchase.purchaseStatus = PurchaseStatus.QueryingAutoRefund;
purchase.autoRefundDeadline = AbsoluteTime.toTimestamp(
purchase.autoRefundDeadline = AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(AbsoluteTime.now(), ar),
);
}
@ -923,7 +924,7 @@ async function unblockBackup(
.forEachAsync(async (bp) => {
bp.state = {
tag: BackupProviderStateTag.Ready,
nextBackupTimestamp: TalerProtocolTimestamp.now(),
nextBackupTimestamp: TalerPreciseTimestamp.now(),
};
tx.backupProviders.put(bp);
});
@ -1422,7 +1423,7 @@ export async function confirmPay(
totalPayCost: Amounts.stringify(payCostInfo),
};
p.lastSessionId = sessionId;
p.timestampAccept = TalerProtocolTimestamp.now();
p.timestampAccept = TalerPreciseTimestamp.now();
p.purchaseStatus = PurchaseStatus.Paying;
await tx.purchases.put(p);
await spendCoins(ws, tx, {
@ -1925,7 +1926,7 @@ async function processPurchaseAutoRefund(
if (
!purchase.autoRefundDeadline ||
AbsoluteTime.isExpired(
AbsoluteTime.fromTimestamp(purchase.autoRefundDeadline),
AbsoluteTime.fromProtocolTimestamp(purchase.autoRefundDeadline),
)
) {
const transitionInfo = await ws.db
@ -2068,9 +2069,9 @@ async function processPurchaseAbortingRefund(
coin_pub: payCoinSelection.coinPubs[i],
refund_amount: Amounts.stringify(payCoinSelection.coinContributions[i]),
rtransaction_id: 0,
execution_time: AbsoluteTime.toTimestamp(
execution_time: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.fromTimestamp(download.contractData.timestamp),
AbsoluteTime.fromProtocolTimestamp(download.contractData.timestamp),
Duration.fromSpec({ seconds: 1 }),
),
),
@ -2267,7 +2268,7 @@ async function storeRefunds(
});
const newRefundGroupId = encodeCrock(randomBytes(32));
const now = TalerProtocolTimestamp.now();
const now = TalerPreciseTimestamp.now();
const download = await expectProposalDownload(ws, purchase);
const currency = Amounts.currencyOf(download.contractData.amount);

View File

@ -78,6 +78,7 @@ import {
TransactionState,
TransactionMajorState,
TransactionMinorState,
TalerPreciseTimestamp,
} from "@gnu-taler/taler-util";
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
import {
@ -728,7 +729,7 @@ export async function initiatePeerPushDebit(
purseExpiration: purseExpiration,
pursePriv: pursePair.priv,
pursePub: pursePair.pub,
timestampCreated: TalerProtocolTimestamp.now(),
timestampCreated: TalerPreciseTimestamp.now(),
status: PeerPushPaymentInitiationStatus.PendingCreatePurse,
contractTerms: contractTerms,
coinSel: {
@ -889,7 +890,7 @@ export async function preparePeerPushCredit(
exchangeBaseUrl: exchangeBaseUrl,
mergePriv: dec.mergePriv,
pursePub: pursePub,
timestamp: TalerProtocolTimestamp.now(),
timestamp: TalerPreciseTimestamp.now(),
contractTermsHash,
status: PeerPushPaymentIncomingStatus.Proposed,
withdrawalGroupId,
@ -1450,7 +1451,7 @@ export async function preparePeerPullDebit(
contractPriv: contractPriv,
exchangeBaseUrl: exchangeBaseUrl,
pursePub: pursePub,
timestampCreated: TalerProtocolTimestamp.now(),
timestampCreated: TalerPreciseTimestamp.now(),
contractTerms,
status: PeerPullPaymentIncomingStatus.Proposed,
totalCostEstimated: Amounts.stringify(totalAmount),
@ -1668,7 +1669,7 @@ export async function processPeerPullCredit(
contractTermsHash: pullIni.contractTermsHash,
flags: WalletAccountMergeFlags.CreateWithPurseFee,
mergePriv: pullIni.mergePriv,
mergeTimestamp: pullIni.mergeTimestamp,
mergeTimestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp),
purseAmount: pullIni.contractTerms.amount,
purseExpiration: purseExpiration,
purseFee: purseFee,
@ -1680,7 +1681,7 @@ export async function processPeerPullCredit(
const reservePurseReqBody: ExchangeReservePurseRequest = {
merge_sig: sigRes.mergeSig,
merge_timestamp: pullIni.mergeTimestamp,
merge_timestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp),
h_contract_terms: pullIni.contractTermsHash,
merge_pub: pullIni.mergePub,
min_age: 0,
@ -1788,8 +1789,8 @@ async function getPreferredExchangeForCurrency(
if (candidate.lastWithdrawal && e.lastWithdrawal) {
if (
AbsoluteTime.cmp(
AbsoluteTime.fromTimestamp(e.lastWithdrawal),
AbsoluteTime.fromTimestamp(candidate.lastWithdrawal),
AbsoluteTime.fromPreciseTimestamp(e.lastWithdrawal),
AbsoluteTime.fromPreciseTimestamp(candidate.lastWithdrawal),
) > 0
) {
candidate = e;
@ -1874,7 +1875,7 @@ export async function initiatePeerPullPayment(
exchangeBaseUrl: exchangeBaseUrl,
});
const mergeTimestamp = TalerProtocolTimestamp.now();
const mergeTimestamp = TalerPreciseTimestamp.now();
const pursePair = await ws.cryptoApi.createEddsaKeypair({});
const mergePair = await ws.cryptoApi.createEddsaKeypair({});

View File

@ -79,7 +79,7 @@ async function gatherExchangePending(
const opTag = TaskIdentifiers.forExchangeUpdate(exch);
let opr = await tx.operationRetries.get(opTag);
const timestampDue =
opr?.retryInfo.nextRetry ?? AbsoluteTime.fromTimestamp(exch.nextUpdate);
opr?.retryInfo.nextRetry ?? AbsoluteTime.fromPreciseTimestamp(exch.nextUpdate);
resp.pendingOperations.push({
type: PendingTaskType.ExchangeUpdate,
...getPendingCommon(ws, opTag, timestampDue),
@ -94,7 +94,7 @@ async function gatherExchangePending(
resp.pendingOperations.push({
type: PendingTaskType.ExchangeCheckRefresh,
...getPendingCommon(ws, opTag, timestampDue),
timestampDue: AbsoluteTime.fromTimestamp(exch.nextRefreshCheck),
timestampDue: AbsoluteTime.fromPreciseTimestamp(exch.nextRefreshCheck),
givesLifeness: false,
exchangeBaseUrl: exch.baseUrl,
});
@ -333,7 +333,7 @@ async function gatherBackupPending(
const opId = TaskIdentifiers.forBackup(bp);
const retryRecord = await tx.operationRetries.get(opId);
if (bp.state.tag === BackupProviderStateTag.Ready) {
const timestampDue = AbsoluteTime.fromTimestamp(
const timestampDue = AbsoluteTime.fromPreciseTimestamp(
bp.state.nextBackupTimestamp,
);
resp.pendingOperations.push({

View File

@ -36,6 +36,7 @@ import {
NotificationType,
RefreshReason,
TalerProtocolTimestamp,
TalerPreciseTimestamp,
URL,
} from "@gnu-taler/taler-util";
import {
@ -424,7 +425,7 @@ export async function processRecoupGroupHandler(
if (!rg2) {
return;
}
rg2.timestampFinished = TalerProtocolTimestamp.now();
rg2.timestampFinished = TalerPreciseTimestamp.now();
if (rg2.scheduleRefreshCoins.length > 0) {
const refreshGroupId = await createRefreshGroup(
ws,
@ -460,7 +461,7 @@ export async function createRecoupGroup(
exchangeBaseUrl: exchangeBaseUrl,
coinPubs: coinPubs,
timestampFinished: undefined,
timestampStarted: TalerProtocolTimestamp.now(),
timestampStarted: TalerPreciseTimestamp.now(),
recoupFinishedPerCoin: coinPubs.map(() => false),
scheduleRefreshCoins: [],
};

View File

@ -48,6 +48,7 @@ import {
RefreshReason,
TalerErrorCode,
TalerErrorDetail,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
TransactionMajorState,
TransactionState,
@ -156,10 +157,10 @@ function updateGroupStatus(rg: RefreshGroupRecord): void {
);
if (allDone) {
if (anyFrozen) {
rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now());
rg.timestampFinished = TalerPreciseTimestamp.now();
rg.operationStatus = RefreshOperationStatus.FinishedWithError;
} else {
rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now());
rg.timestampFinished = TalerPreciseTimestamp.now();
rg.operationStatus = RefreshOperationStatus.Finished;
}
}
@ -1046,12 +1047,12 @@ export async function createRefreshGroup(
estimatedOutputPerCoin: estimatedOutputPerCoin.map((x) =>
Amounts.stringify(x),
),
timestampCreated: TalerProtocolTimestamp.now(),
timestampCreated: TalerPreciseTimestamp.now(),
};
if (oldCoinPubs.length == 0) {
logger.warn("created refresh group with zero coins");
refreshGroup.timestampFinished = TalerProtocolTimestamp.now();
refreshGroup.timestampFinished = TalerPreciseTimestamp.now();
refreshGroup.operationStatus = RefreshOperationStatus.Finished;
}
@ -1075,8 +1076,8 @@ export async function createRefreshGroup(
* Timestamp after which the wallet would do the next check for an auto-refresh.
*/
function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime {
const expireWithdraw = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw);
const expireDeposit = AbsoluteTime.fromTimestamp(d.stampExpireDeposit);
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit);
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
const deltaDiv = durationMul(delta, 0.75);
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
@ -1086,8 +1087,8 @@ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime {
* Timestamp after which the wallet would do an auto-refresh.
*/
function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime {
const expireWithdraw = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw);
const expireDeposit = AbsoluteTime.fromTimestamp(d.stampExpireDeposit);
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit);
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
const deltaDiv = durationMul(delta, 0.5);
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
@ -1174,7 +1175,7 @@ export async function autoRefresh(
logger.info(
`next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`,
);
exchange.nextRefreshCheck = AbsoluteTime.toTimestamp(minCheckThreshold);
exchange.nextRefreshCheck = AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
await tx.exchanges.put(exchange);
});
return OperationAttemptResult.finishedEmpty();

View File

@ -536,7 +536,7 @@ export async function runIntegrationTest2(
partialContractTerms: {
amount: `${currency}:1`,
summary: "Payment Peer Push Test",
purse_expiration: AbsoluteTime.toTimestamp(
purse_expiration: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
Duration.fromSpec({ hours: 1 }),
@ -557,7 +557,7 @@ export async function runIntegrationTest2(
partialContractTerms: {
amount: `${currency}:1`,
summary: "Payment Peer Pull Test",
purse_expiration: AbsoluteTime.toTimestamp(
purse_expiration: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
Duration.fromSpec({ hours: 1 }),

View File

@ -33,6 +33,7 @@ import {
parseTipUri,
PrepareTipResult,
TalerErrorCode,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
TipPlanchetDetail,
TransactionMajorState,
@ -160,7 +161,7 @@ export async function prepareTip(
exchangeBaseUrl: tipPickupStatus.exchange_url,
next_url: tipPickupStatus.next_url,
merchantBaseUrl: res.merchantBaseUrl,
createdTimestamp: TalerProtocolTimestamp.now(),
createdTimestamp: TalerPreciseTimestamp.now(),
merchantTipId: res.merchantTipId,
tipAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue),
denomsSel: selectedDenoms,
@ -365,7 +366,7 @@ export async function processTip(
if (tr.pickedUpTimestamp) {
return;
}
tr.pickedUpTimestamp = TalerProtocolTimestamp.now();
tr.pickedUpTimestamp = TalerPreciseTimestamp.now();
await tx.tips.put(tr);
for (const cr of newCoinRecords) {
await makeCoinAvailable(ws, tx, cr);
@ -390,7 +391,7 @@ export async function acceptTip(
logger.error("tip not found");
return undefined;
}
tipRecord.acceptedTimestamp = TalerProtocolTimestamp.now();
tipRecord.acceptedTimestamp = TalerPreciseTimestamp.now();
await tx.tips.put(tipRecord);
return tipRecord;

View File

@ -30,6 +30,7 @@ import {
stringifyPayPullUri,
stringifyPayPushUri,
TalerErrorCode,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
Transaction,
TransactionByIdRequest,
@ -472,7 +473,7 @@ function buildTransactionForPeerPullCredit(
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
// Old transactions don't have it!
timestamp: pullCredit.mergeTimestamp ?? TalerProtocolTimestamp.now(),
timestamp: pullCredit.mergeTimestamp ?? TalerPreciseTimestamp.now(),
info: {
expiration: wsr.wgInfo.contractTerms.purse_expiration,
summary: wsr.wgInfo.contractTerms.summary,
@ -1171,8 +1172,8 @@ export async function getTransactions(
const txCmp = (h1: Transaction, h2: Transaction) => {
const tsCmp = AbsoluteTime.cmp(
AbsoluteTime.fromTimestamp(h1.timestamp),
AbsoluteTime.fromTimestamp(h2.timestamp),
AbsoluteTime.fromPreciseTimestamp(h1.timestamp),
AbsoluteTime.fromPreciseTimestamp(h2.timestamp),
);
if (tsCmp === 0) {
return Math.sign(txOrder[h1.type] - txOrder[h2.type]);

View File

@ -66,6 +66,7 @@ import {
TransactionState,
TransactionMajorState,
TransactionMinorState,
TalerPreciseTimestamp,
} from "@gnu-taler/taler-util";
import { EddsaKeypair } from "../crypto/cryptoImplementation.js";
import {
@ -1327,7 +1328,7 @@ export async function processWithdrawalGroup(
}
const txStatusOld = computeWithdrawalTransactionStatus(wg);
wg.status = WithdrawalGroupStatus.Finished;
wg.timestampFinish = TalerProtocolTimestamp.now();
wg.timestampFinish = TalerPreciseTimestamp.now();
const txStatusNew = computeWithdrawalTransactionStatus(wg);
await tx.withdrawalGroups.put(wg);
return {
@ -1428,7 +1429,7 @@ export async function processWithdrawalGroup(
logger.info(`now withdrawn ${numFinished} of ${numTotalCoins} coins`);
if (wg.timestampFinish === undefined && numFinished === numTotalCoins) {
finishedForFirstTime = true;
wg.timestampFinish = TalerProtocolTimestamp.now();
wg.timestampFinish = TalerPreciseTimestamp.now();
wg.status = WithdrawalGroupStatus.Finished;
}
@ -1613,8 +1614,8 @@ export async function getExchangeWithdrawalInfo(
}
if (
AbsoluteTime.cmp(
AbsoluteTime.fromTimestamp(expireDeposit),
AbsoluteTime.fromTimestamp(earliestDepositExpiration),
AbsoluteTime.fromProtocolTimestamp(expireDeposit),
AbsoluteTime.fromProtocolTimestamp(earliestDepositExpiration),
) < 0
) {
earliestDepositExpiration = expireDeposit;
@ -1910,7 +1911,7 @@ async function registerReserveWithBank(
if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
throw Error("invariant failed");
}
r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp(
r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toPreciseTimestamp(
AbsoluteTime.now(),
);
const oldTxState = computeWithdrawalTransactionStatus(r);
@ -1994,7 +1995,7 @@ async function processReserveBankStatus(
if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
throw Error("invariant failed");
}
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
const oldTxState = computeWithdrawalTransactionStatus(r);
r.wgInfo.bankInfo.timestampBankConfirmed = now;
r.status = WithdrawalGroupStatus.FailedBankAborted;
@ -2044,7 +2045,7 @@ async function processReserveBankStatus(
const oldTxState = computeWithdrawalTransactionStatus(r);
if (status.transfer_done) {
logger.info("withdrawal: transfer confirmed by bank.");
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
r.wgInfo.bankInfo.timestampBankConfirmed = now;
r.status = WithdrawalGroupStatus.PendingQueryingStatus;
// FIXME: Notification is deprecated with DD37.
@ -2105,7 +2106,7 @@ export async function internalCreateWithdrawalGroup(
): Promise<WithdrawalGroupRecord> {
const reserveKeyPair =
args.reserveKeyPair ?? (await ws.cryptoApi.createEddsaKeypair({}));
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
const secretSeed = encodeCrock(getRandomBytes(32));
const canonExchange = canonicalizeBaseUrl(args.exchangeBaseUrl);
const amount = args.amount;
@ -2200,7 +2201,7 @@ export async function internalCreateWithdrawalGroup(
const exchange = await tx.exchanges.get(withdrawalGroup.exchangeBaseUrl);
if (exchange) {
exchange.lastWithdrawal = TalerProtocolTimestamp.now();
exchange.lastWithdrawal = TalerPreciseTimestamp.now();
await tx.exchanges.put(exchange);
}

View File

@ -577,8 +577,8 @@ export async function selectCandidates(
]?.find((x) => {
return AbsoluteTime.isBetween(
AbsoluteTime.now(),
AbsoluteTime.fromTimestamp(x.startStamp),
AbsoluteTime.fromTimestamp(x.endStamp),
AbsoluteTime.fromProtocolTimestamp(x.startStamp),
AbsoluteTime.fromProtocolTimestamp(x.endStamp),
);
})?.wireFee;
if (wireFeeStr) {

View File

@ -42,7 +42,7 @@ const VALUES: AmountString[] = Array.from({ length: 10 }).map(
(undef, t) => `USD:${t}`,
);
const TIMESTAMPS = Array.from({ length: 20 }).map((undef, t_s) => ({ t_s }));
const ABS_TIME = TIMESTAMPS.map((m) => AbsoluteTime.fromTimestamp(m));
const ABS_TIME = TIMESTAMPS.map((m) => AbsoluteTime.fromProtocolTimestamp(m));
function normalize(
list: DenominationInfo[],

View File

@ -326,7 +326,7 @@ export function createTimeline<Type extends object>(
fee: Amounts.stringify(fee),
group,
id,
moment: AbsoluteTime.fromTimestamp(stampStart),
moment: AbsoluteTime.fromProtocolTimestamp(stampStart),
denom,
});
ps.push({
@ -334,7 +334,7 @@ export function createTimeline<Type extends object>(
fee: Amounts.stringify(fee),
group,
id,
moment: AbsoluteTime.fromTimestamp(stampEnd),
moment: AbsoluteTime.fromProtocolTimestamp(stampEnd),
denom,
});
return ps;
@ -457,8 +457,8 @@ export function isWithdrawableDenom(
denomselAllowLate?: boolean,
): boolean {
const now = AbsoluteTime.now();
const start = AbsoluteTime.fromTimestamp(d.stampStart);
const withdrawExpire = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw);
const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart);
const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
const started = AbsoluteTime.cmp(now, start) >= 0;
let lastPossibleWithdraw: AbsoluteTime;
if (denomselAllowLate) {

View File

@ -136,7 +136,7 @@ export function PendingTransactionsView({
</Typography>
&nbsp;-&nbsp;
<Time
timestamp={AbsoluteTime.fromTimestamp(t.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(t.timestamp)}
format="dd MMMM yyyy"
/>
</Grid>

View File

@ -179,7 +179,7 @@ export function HiddenView({ showHandler }: States.Hidden): VNode {
}
export function ShowView({ contractTerms, hideHandler }: States.Show): VNode {
const createdAt = AbsoluteTime.fromTimestamp(contractTerms.timestamp);
const createdAt = AbsoluteTime.fromProtocolTimestamp(contractTerms.timestamp);
const { i18n } = useTranslationContext();
return (
@ -266,7 +266,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode {
<td>
{contractTerms.deliveryDate && (
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
contractTerms.deliveryDate,
)}
format="dd MMMM yyyy, HH:mm"
@ -299,7 +299,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode {
<td>
{contractTerms.timestamp && (
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
contractTerms.timestamp,
)}
format="dd MMMM yyyy, HH:mm"
@ -314,7 +314,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode {
<td>
{
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
contractTerms.refundDeadline,
)}
format="dd MMMM yyyy, HH:mm"
@ -349,7 +349,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode {
<td>
{
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
contractTerms.payDeadline,
)}
format="dd MMMM yyyy, HH:mm"

View File

@ -53,7 +53,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={new URL(tx.exchangeBaseUrl).hostname}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"W"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -76,7 +76,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={new URL(tx.exchangeBaseUrl).hostname}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"I"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -100,7 +100,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
debitCreditIndicator={"debit"}
title={tx.info.merchant.name}
subtitle={tx.info.summary}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"P"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -121,7 +121,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
? tx.paymentInfo.merchant.name
: "--unknown merchant--"
} //FIXME: DD37 wallet-core is not returning this value
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"R"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -137,7 +137,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={new URL(tx.merchantBaseUrl).hostname}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"T"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -153,7 +153,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={"Refresh"}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"R"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -169,7 +169,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"debit"}
title={tx.targetPaytoUri}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"D"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -185,7 +185,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={tx.info.summary || "Invoice"}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"I"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -201,7 +201,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"debit"}
title={tx.info.summary || "Invoice"}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"I"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -217,7 +217,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"credit"}
title={tx.info.summary || "Transfer"}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"T"}
pending={
tx.txState.major === TransactionMajorState.Pending
@ -233,7 +233,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
amount={tx.amountEffective}
debitCreditIndicator={"debit"}
title={tx.info.summary || "Transfer"}
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
iconPath={"T"}
pending={
tx.txState.major === TransactionMajorState.Pending

View File

@ -123,7 +123,7 @@ export function useComponentState({
raw,
goToWalletManualWithdraw,
summary,
expiration: expiration ? AbsoluteTime.fromTimestamp(expiration) : undefined,
expiration: expiration ? AbsoluteTime.fromProtocolTimestamp(expiration) : undefined,
};
if (!foundBalance) {

View File

@ -93,7 +93,7 @@ export function BaseView(state: SupportedStates): VNode {
title={i18n.str`Valid until`}
text={
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
contractTerms.pay_deadline,
)}
format="dd MMMM yyyy, HH:mm"

View File

@ -86,7 +86,7 @@ export function useComponentState({
onClick: pushAlertOnError(accept),
},
summary,
expiration: expiration ? AbsoluteTime.fromTimestamp(expiration) : undefined,
expiration: expiration ? AbsoluteTime.fromProtocolTimestamp(expiration) : undefined,
cancel: {
onClick: pushAlertOnError(onClose),
},

View File

@ -26,7 +26,7 @@ import {
ShowRecoveryInfo,
} from "./BackupPage.js";
import * as tests from "@gnu-taler/web-util/testing";
import { TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { TalerPreciseTimestamp, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
export default {
title: "backup",
@ -39,7 +39,7 @@ export const LotOfProviders = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],
@ -60,7 +60,7 @@ export const LotOfProviders = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],
@ -171,7 +171,7 @@ export const OneProvider = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],

View File

@ -199,7 +199,7 @@ export function BackupView({
status={provider.paymentStatus}
timestamp={
provider.lastSuccessfulBackupTimestamp
? AbsoluteTime.fromTimestamp(
? AbsoluteTime.fromPreciseTimestamp(
provider.lastSuccessfulBackupTimestamp,
)
: undefined

View File

@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
import { AbsoluteTime, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { AbsoluteTime, TalerPreciseTimestamp, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
import * as tests from "@gnu-taler/web-util/testing";
import { ProviderView as TestedComponent } from "./ProviderDetailPage.js";
@ -40,7 +40,7 @@ export const Active = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],
@ -64,9 +64,9 @@ export const ActiveErrorSync = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
lastAttemptedBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925078),
TalerPreciseTimestamp.fromSeconds(1625063925078),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],
@ -99,7 +99,7 @@ export const ActiveBackupProblemUnreadable = tests.createExample(
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925),
TalerPreciseTimestamp.fromSeconds(1625063925),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],
@ -127,7 +127,7 @@ export const ActiveBackupProblemDevice = tests.createExample(TestedComponent, {
name: "sync.demo",
syncProviderBaseUrl: "http://sync.taler:9967/",
lastSuccessfulBackupTimestamp:
TalerProtocolTimestamp.fromSeconds(1625063925078),
TalerPreciseTimestamp.fromSeconds(1625063925078),
paymentProposalIds: [
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
],

View File

@ -151,7 +151,7 @@ export function ProviderView({
}: ViewProps): VNode {
const { i18n } = useTranslationContext();
const lb = info.lastSuccessfulBackupTimestamp
? AbsoluteTime.fromTimestamp(info.lastSuccessfulBackupTimestamp)
? AbsoluteTime.fromPreciseTimestamp(info.lastSuccessfulBackupTimestamp)
: undefined;
const isPaid =
info.paymentStatus.type === ProviderPaymentType.Paid ||

View File

@ -23,6 +23,7 @@ import {
AbsoluteTime,
PaymentStatus,
RefreshReason,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
TransactionCommon,
TransactionDeposit,
@ -245,7 +246,7 @@ export const WithdrawFiveMinutesAgo = tests.createExample(
() => ({
transaction: {
...exampleData.withdraw,
timestamp: TalerProtocolTimestamp.fromSeconds(
timestamp: TalerPreciseTimestamp.fromSeconds(
new Date().getTime() / 1000 - 60 * 5,
),
},
@ -257,7 +258,7 @@ export const WithdrawFiveMinutesAgoAndPending = tests.createExample(
() => ({
transaction: {
...exampleData.withdraw,
timestamp: TalerProtocolTimestamp.fromSeconds(
timestamp: TalerPreciseTimestamp.fromSeconds(
new Date().getTime() / 1000 - 60 * 5,
),
txState: {

View File

@ -25,6 +25,7 @@ import {
parsePaytoUri,
PaytoUri,
stringifyPaytoUri,
TalerPreciseTimestamp,
TalerProtocolTimestamp,
Transaction,
TransactionDeposit,
@ -585,7 +586,7 @@ export function TransactionView({
on{" "}
{
<Time
timestamp={AbsoluteTime.fromTimestamp(
timestamp={AbsoluteTime.fromProtocolTimestamp(
r.timestamp,
)}
format="dd MMMM yyyy"
@ -671,7 +672,7 @@ export function TransactionView({
if (transaction.type === TransactionType.Deposit) {
const payto = parsePaytoUri(transaction.targetPaytoUri);
const wireTime = AbsoluteTime.fromTimestamp(
const wireTime = AbsoluteTime.fromProtocolTimestamp(
transaction.wireTransferDeadline,
);
const shouldBeWired = wireTime.t_ms !== "never" && isPast(wireTime.t_ms);
@ -1204,7 +1205,7 @@ function DeliveryDetails({
</td>
<td>
<Time
timestamp={AbsoluteTime.fromTimestamp(date)}
timestamp={AbsoluteTime.fromProtocolTimestamp(date)}
format="dd MMMM yyyy, HH:mm"
/>
</td>
@ -1768,7 +1769,7 @@ function Header({
kind,
type,
}: {
timestamp: TalerProtocolTimestamp;
timestamp: TalerPreciseTimestamp;
total: AmountJson;
children: ComponentChildren;
kind: Kind;
@ -1785,7 +1786,7 @@ function Header({
<div>
<SubTitle>{children}</SubTitle>
<Time
timestamp={AbsoluteTime.fromTimestamp(timestamp)}
timestamp={AbsoluteTime.fromPreciseTimestamp(timestamp)}
format="dd MMMM yyyy, HH:mm"
/>
</div>