gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: taler-util,wallet-core: imple


From: gnunet
Subject: [taler-wallet-core] branch master updated: taler-util,wallet-core: implement TalerPreciseTimestamp
Date: Fri, 26 May 2023 12:19:44 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new cd8f76db6 taler-util,wallet-core: implement TalerPreciseTimestamp
cd8f76db6 is described below

commit cd8f76db61f4a1ab1a8a8a4d29b2f3e863b59854
Author: Florian Dold <florian@dold.me>
AuthorDate: Fri May 26 12:19:32 2023 +0200

    taler-util,wallet-core: implement TalerPreciseTimestamp
    
    Fixes #7703
---
 packages/anastasis-core/src/index.ts               |  2 +-
 .../integrationtests/test-age-restrictions-peer.ts |  2 +-
 .../integrationtests/test-exchange-timetravel.ts   | 10 +--
 .../src/integrationtests/test-libeufin-basic.ts    |  2 +-
 .../src/integrationtests/test-peer-to-peer-pull.ts |  2 +-
 .../src/integrationtests/test-peer-to-peer-push.ts |  2 +-
 .../src/integrationtests/test-refund-gone.ts       |  2 +-
 packages/taler-util/src/backup-types.ts            | 36 +++++------
 packages/taler-util/src/time.ts                    | 58 ++++++++++++++++--
 packages/taler-util/src/transactions-types.ts      |  4 +-
 packages/taler-wallet-cli/src/index.ts             |  4 +-
 .../src/crypto/workers/crypto-dispatcher.test.ts   |  4 +-
 packages/taler-wallet-core/src/db.ts               | 71 +++++++++++-----------
 packages/taler-wallet-core/src/dbless.ts           |  2 +-
 .../taler-wallet-core/src/operations/attention.ts  |  3 +-
 .../src/operations/backup/export.ts                |  5 +-
 .../src/operations/backup/import.ts                |  5 +-
 .../src/operations/backup/index.ts                 | 21 ++++---
 .../taler-wallet-core/src/operations/deposits.ts   | 27 ++++----
 .../taler-wallet-core/src/operations/exchanges.ts  | 23 ++++---
 .../src/operations/pay-merchant.ts                 | 19 +++---
 .../taler-wallet-core/src/operations/pay-peer.ts   | 17 +++---
 .../taler-wallet-core/src/operations/pending.ts    |  6 +-
 .../taler-wallet-core/src/operations/recoup.ts     |  5 +-
 .../taler-wallet-core/src/operations/refresh.ts    | 19 +++---
 .../taler-wallet-core/src/operations/testing.ts    |  4 +-
 packages/taler-wallet-core/src/operations/tip.ts   |  7 ++-
 .../src/operations/transactions.ts                 |  7 ++-
 .../taler-wallet-core/src/operations/withdraw.ts   | 19 +++---
 .../taler-wallet-core/src/util/coinSelection.ts    |  4 +-
 .../src/util/denominations.test.ts                 |  2 +-
 .../taler-wallet-core/src/util/denominations.ts    |  8 +--
 .../src/components/PendingTransactions.tsx         |  2 +-
 .../src/components/ShowFullContractTermPopup.tsx   | 10 +--
 .../src/components/TransactionItem.tsx             | 22 +++----
 .../src/cta/InvoicePay/state.ts                    |  2 +-
 .../src/cta/Payment/views.tsx                      |  2 +-
 .../src/cta/TransferPickup/state.ts                |  2 +-
 .../src/wallet/Backup.stories.tsx                  |  8 +--
 .../src/wallet/BackupPage.tsx                      |  2 +-
 .../src/wallet/ProviderDetail.stories.tsx          | 12 ++--
 .../src/wallet/ProviderDetailPage.tsx              |  2 +-
 .../src/wallet/Transaction.stories.tsx             |  5 +-
 .../src/wallet/Transaction.tsx                     | 11 ++--
 44 files changed, 274 insertions(+), 208 deletions(-)

diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index 8cb86cd85..5e7397450 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -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.
diff --git 
a/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts 
b/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts
index 0bb811f39..eae04cd2e 100644
--- a/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts
+++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts
@@ -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 }),
diff --git 
a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts 
b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts
index 7f94628a6..dee00d1ff 100644
--- a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts
+++ b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts
@@ -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(
diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts 
b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts
index a58429245..f03b63f50 100644
--- a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts
+++ b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts
@@ -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 });
diff --git 
a/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts 
b/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts
index 58a1f271e..557954f66 100644
--- a/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts
+++ b/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts
@@ -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 }),
diff --git 
a/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts 
b/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts
index 60ccce000..b179f6722 100644
--- a/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts
+++ b/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts
@@ -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 }),
diff --git a/packages/taler-harness/src/integrationtests/test-refund-gone.ts 
b/packages/taler-harness/src/integrationtests/test-refund-gone.ts
index 7bebd6239..5f226c7dd 100644
--- a/packages/taler-harness/src/integrationtests/test-refund-gone.ts
+++ b/packages/taler-harness/src/integrationtests/test-refund-gone.ts
@@ -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({
diff --git a/packages/taler-util/src/backup-types.ts 
b/packages/taler-util/src/backup-types.ts
index f7bf5ef30..2bfe6b886 100644
--- a/packages/taler-util/src/backup-types.ts
+++ b/packages/taler-util/src/backup-types.ts
@@ -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 {
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 6ada13e25..697bde5c0 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -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" };
     }
diff --git a/packages/taler-util/src/transactions-types.ts 
b/packages/taler-util/src/transactions-types.ts
index 03c894fe6..38cbea736 100644
--- a/packages/taler-util/src/transactions-types.ts
+++ b/packages/taler-util/src/transactions-types.ts
@@ -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.
diff --git a/packages/taler-wallet-cli/src/index.ts 
b/packages/taler-wallet-cli/src/index.ts
index 60db5abe8..a9dec8529 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -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),
           },
         },
       );
diff --git 
a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts 
b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts
index 1e9d82f66..96e2ee735 100644
--- a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts
@@ -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",
           },
diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index 8d66ee27b..12e799c71 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -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;
 
diff --git a/packages/taler-wallet-core/src/dbless.ts 
b/packages/taler-wallet-core/src/dbless.ts
index 87e3984b6..68cce2b8d 100644
--- a/packages/taler-wallet-core/src/dbless.ts
+++ b/packages/taler-wallet-core/src/dbless.ts
@@ -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;
diff --git a/packages/taler-wallet-core/src/operations/attention.ts 
b/packages/taler-wallet-core/src/operations/attention.ts
index 95db7bde0..b802b15cd 100644
--- a/packages/taler-wallet-core/src/operations/attention.ts
+++ b/packages/taler-wallet-core/src/operations/attention.ts
@@ -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(),
       });
     });
 }
diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts 
b/packages/taler-wallet-core/src/operations/backup/export.ts
index 7b245a4eb..ff5f1e177 100644
--- a/packages/taler-wallet-core/src/operations/backup/export.ts
+++ b/packages/taler-wallet-core/src/operations/backup/export.ts
@@ -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({
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts 
b/packages/taler-wallet-core/src/operations/backup/import.ts
index 5375a58bb..6d78b2be0 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -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,
         });
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts 
b/packages/taler-wallet-core/src/operations/backup/index.ts
index 59e99b505..f726167da 100644
--- a/packages/taler-wallet-core/src/operations/backup/index.ts
+++ b/packages/taler-wallet-core/src/operations/backup/index.ts
@@ -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))],
           });
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts 
b/packages/taler-wallet-core/src/operations/deposits.ts
index a36091165..de881ddd2 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -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;
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts 
b/packages/taler-wallet-core/src/operations/exchanges.ts
index d8fb95755..142e0cf03 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -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);
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts 
b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index 854202b6a..4ea41c695 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -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);
diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts 
b/packages/taler-wallet-core/src/operations/pay-peer.ts
index 108be7339..f464948f8 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer.ts
@@ -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({});
diff --git a/packages/taler-wallet-core/src/operations/pending.ts 
b/packages/taler-wallet-core/src/operations/pending.ts
index 54b12383b..7e098b19c 100644
--- a/packages/taler-wallet-core/src/operations/pending.ts
+++ b/packages/taler-wallet-core/src/operations/pending.ts
@@ -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({
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts 
b/packages/taler-wallet-core/src/operations/recoup.ts
index 982f3cf8c..1f36117ee 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -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: [],
   };
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts 
b/packages/taler-wallet-core/src/operations/refresh.ts
index 14556f3c0..c46344313 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -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();
diff --git a/packages/taler-wallet-core/src/operations/testing.ts 
b/packages/taler-wallet-core/src/operations/testing.ts
index e5794ad93..ef5aa907d 100644
--- a/packages/taler-wallet-core/src/operations/testing.ts
+++ b/packages/taler-wallet-core/src/operations/testing.ts
@@ -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 }),
diff --git a/packages/taler-wallet-core/src/operations/tip.ts 
b/packages/taler-wallet-core/src/operations/tip.ts
index 417f06dc2..524970faa 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -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;
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts 
b/packages/taler-wallet-core/src/operations/transactions.ts
index 894becca7..481ffe8bb 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -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]);
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts 
b/packages/taler-wallet-core/src/operations/withdraw.ts
index c0566bf4d..586aa50f5 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -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);
       }
 
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts 
b/packages/taler-wallet-core/src/util/coinSelection.ts
index af6dab2bb..f4066bf51 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -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) {
diff --git a/packages/taler-wallet-core/src/util/denominations.test.ts 
b/packages/taler-wallet-core/src/util/denominations.test.ts
index 551e06a33..25dbda081 100644
--- a/packages/taler-wallet-core/src/util/denominations.test.ts
+++ b/packages/taler-wallet-core/src/util/denominations.test.ts
@@ -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[],
diff --git a/packages/taler-wallet-core/src/util/denominations.ts 
b/packages/taler-wallet-core/src/util/denominations.ts
index 5cc57bdab..ecf8c5671 100644
--- a/packages/taler-wallet-core/src/util/denominations.ts
+++ b/packages/taler-wallet-core/src/util/denominations.ts
@@ -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) {
diff --git 
a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx 
b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
index 3866fc991..9c11170cd 100644
--- a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
+++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
@@ -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>
diff --git 
a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
 
b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
index 9cbc2899f..392a7d0e8 100644
--- 
a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
+++ 
b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
@@ -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"
diff --git 
a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx 
b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
index 124729349..15669e63d 100644
--- a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
+++ b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
@@ -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
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts 
b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
index 690474a86..10f1ee849 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
@@ -123,7 +123,7 @@ export function useComponentState({
     raw,
     goToWalletManualWithdraw,
     summary,
-    expiration: expiration ? AbsoluteTime.fromTimestamp(expiration) : 
undefined,
+    expiration: expiration ? AbsoluteTime.fromProtocolTimestamp(expiration) : 
undefined,
   };
 
   if (!foundBalance) {
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx 
b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
index ea3d93f3f..764036dad 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
@@ -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"
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts 
b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
index 9b309ce2f..7711498e1 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
@@ -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),
     },
diff --git a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
index b927ffbae..ddcba6fae 100644
--- a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
@@ -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",
       ],
diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
index 8acfe3ecf..5ae52db6f 100644
--- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
@@ -199,7 +199,7 @@ export function BackupView({
             status={provider.paymentStatus}
             timestamp={
               provider.lastSuccessfulBackupTimestamp
-                ? AbsoluteTime.fromTimestamp(
+                ? AbsoluteTime.fromPreciseTimestamp(
                     provider.lastSuccessfulBackupTimestamp,
                   )
                 : undefined
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
index 682f03f39..9c03d18f6 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
@@ -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",
     ],
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
index bf7bc0669..19ae39106 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
@@ -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 ||
diff --git 
a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
index b2a8de014..c2bceb067 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
@@ -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: {
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 9541cc33f..39175186f 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -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>

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]