summaryrefslogtreecommitdiff
path: root/packages/taler-util/src
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-03-18 15:32:41 +0100
committerFlorian Dold <florian@dold.me>2022-03-21 19:20:48 +0100
commitf8d12f7b0d4af1b1769b89e80c87f9c169678564 (patch)
tree2478696c7bc1efc6d090b93aa340de542a7dccd9 /packages/taler-util/src
parent32cd54e11d80bde0274b3c0238f8f5bd00ff83cb (diff)
downloadwallet-core-f8d12f7b0d4af1b1769b89e80c87f9c169678564.tar.gz
wallet-core-f8d12f7b0d4af1b1769b89e80c87f9c169678564.tar.bz2
wallet-core-f8d12f7b0d4af1b1769b89e80c87f9c169678564.zip
wallet: t_s/d_us migration
Diffstat (limited to 'packages/taler-util/src')
-rw-r--r--packages/taler-util/src/RequestThrottler.ts10
-rw-r--r--packages/taler-util/src/ReserveTransaction.ts96
-rw-r--r--packages/taler-util/src/backupTypes.ts74
-rw-r--r--packages/taler-util/src/talerTypes.ts51
-rw-r--r--packages/taler-util/src/time.ts356
-rw-r--r--packages/taler-util/src/transactionsTypes.ts4
-rw-r--r--packages/taler-util/src/types-test.ts16
-rw-r--r--packages/taler-util/src/walletTypes.ts14
8 files changed, 340 insertions, 281 deletions
diff --git a/packages/taler-util/src/RequestThrottler.ts b/packages/taler-util/src/RequestThrottler.ts
index 7689b4215..a151cc634 100644
--- a/packages/taler-util/src/RequestThrottler.ts
+++ b/packages/taler-util/src/RequestThrottler.ts
@@ -15,7 +15,7 @@
*/
import { Logger } from "./logging.js";
-import { getTimestampNow, timestampCmp, timestampDifference } from "./time.js";
+import { AbsoluteTime } from "./time.js";
/**
* Implementation of token bucket throttling.
@@ -46,16 +46,16 @@ class OriginState {
tokensSecond: number = MAX_PER_SECOND;
tokensMinute: number = MAX_PER_MINUTE;
tokensHour: number = MAX_PER_HOUR;
- private lastUpdate = getTimestampNow();
+ private lastUpdate = AbsoluteTime.now();
private refill(): void {
- const now = getTimestampNow();
- if (timestampCmp(now, this.lastUpdate) < 0) {
+ const now = AbsoluteTime.now();
+ if (AbsoluteTime.cmp(now, this.lastUpdate) < 0) {
// Did the system time change?
this.lastUpdate = now;
return;
}
- const d = timestampDifference(now, this.lastUpdate);
+ const d = AbsoluteTime.difference(now, this.lastUpdate);
if (d.d_ms === "forever") {
throw Error("assertion failed");
}
diff --git a/packages/taler-util/src/ReserveTransaction.ts b/packages/taler-util/src/ReserveTransaction.ts
index b282ef189..50610483f 100644
--- a/packages/taler-util/src/ReserveTransaction.ts
+++ b/packages/taler-util/src/ReserveTransaction.ts
@@ -38,7 +38,11 @@ import {
EddsaPublicKeyString,
CoinPublicKeyString,
} from "./talerTypes";
-import { Timestamp, codecForTimestamp } from "./time.js";
+import {
+ AbsoluteTime,
+ codecForTimestamp,
+ TalerProtocolTimestamp,
+} from "./time.js";
export enum ReserveTransactionType {
Withdraw = "WITHDRAW",
@@ -98,7 +102,7 @@ export interface ReserveCreditTransaction {
/**
* Timestamp of the incoming wire transfer.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
}
export interface ReserveClosingTransaction {
@@ -139,7 +143,7 @@ export interface ReserveClosingTransaction {
/**
* Time when the reserve was closed.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
}
export interface ReserveRecoupTransaction {
@@ -165,7 +169,7 @@ export interface ReserveRecoupTransaction {
/**
* Time when the funds were paid back into the reserve.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
/**
* Public key of the coin that was paid back.
@@ -182,46 +186,50 @@ export type ReserveTransaction =
| ReserveClosingTransaction
| ReserveRecoupTransaction;
-export const codecForReserveWithdrawTransaction = (): Codec<ReserveWithdrawTransaction> =>
- buildCodecForObject<ReserveWithdrawTransaction>()
- .property("amount", codecForString())
- .property("h_coin_envelope", codecForString())
- .property("h_denom_pub", codecForString())
- .property("reserve_sig", codecForString())
- .property("type", codecForConstString(ReserveTransactionType.Withdraw))
- .property("withdraw_fee", codecForString())
- .build("ReserveWithdrawTransaction");
-
-export const codecForReserveCreditTransaction = (): Codec<ReserveCreditTransaction> =>
- buildCodecForObject<ReserveCreditTransaction>()
- .property("amount", codecForString())
- .property("sender_account_url", codecForString())
- .property("timestamp", codecForTimestamp)
- .property("wire_reference", codecForNumber())
- .property("type", codecForConstString(ReserveTransactionType.Credit))
- .build("ReserveCreditTransaction");
-
-export const codecForReserveClosingTransaction = (): Codec<ReserveClosingTransaction> =>
- buildCodecForObject<ReserveClosingTransaction>()
- .property("amount", codecForString())
- .property("closing_fee", codecForString())
- .property("exchange_pub", codecForString())
- .property("exchange_sig", codecForString())
- .property("h_wire", codecForString())
- .property("timestamp", codecForTimestamp)
- .property("type", codecForConstString(ReserveTransactionType.Closing))
- .property("wtid", codecForString())
- .build("ReserveClosingTransaction");
-
-export const codecForReserveRecoupTransaction = (): Codec<ReserveRecoupTransaction> =>
- buildCodecForObject<ReserveRecoupTransaction>()
- .property("amount", codecForString())
- .property("coin_pub", codecForString())
- .property("exchange_pub", codecForString())
- .property("exchange_sig", codecForString())
- .property("timestamp", codecForTimestamp)
- .property("type", codecForConstString(ReserveTransactionType.Recoup))
- .build("ReserveRecoupTransaction");
+export const codecForReserveWithdrawTransaction =
+ (): Codec<ReserveWithdrawTransaction> =>
+ buildCodecForObject<ReserveWithdrawTransaction>()
+ .property("amount", codecForString())
+ .property("h_coin_envelope", codecForString())
+ .property("h_denom_pub", codecForString())
+ .property("reserve_sig", codecForString())
+ .property("type", codecForConstString(ReserveTransactionType.Withdraw))
+ .property("withdraw_fee", codecForString())
+ .build("ReserveWithdrawTransaction");
+
+export const codecForReserveCreditTransaction =
+ (): Codec<ReserveCreditTransaction> =>
+ buildCodecForObject<ReserveCreditTransaction>()
+ .property("amount", codecForString())
+ .property("sender_account_url", codecForString())
+ .property("timestamp", codecForTimestamp)
+ .property("wire_reference", codecForNumber())
+ .property("type", codecForConstString(ReserveTransactionType.Credit))
+ .build("ReserveCreditTransaction");
+
+export const codecForReserveClosingTransaction =
+ (): Codec<ReserveClosingTransaction> =>
+ buildCodecForObject<ReserveClosingTransaction>()
+ .property("amount", codecForString())
+ .property("closing_fee", codecForString())
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("h_wire", codecForString())
+ .property("timestamp", codecForTimestamp)
+ .property("type", codecForConstString(ReserveTransactionType.Closing))
+ .property("wtid", codecForString())
+ .build("ReserveClosingTransaction");
+
+export const codecForReserveRecoupTransaction =
+ (): Codec<ReserveRecoupTransaction> =>
+ buildCodecForObject<ReserveRecoupTransaction>()
+ .property("amount", codecForString())
+ .property("coin_pub", codecForString())
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("timestamp", codecForTimestamp)
+ .property("type", codecForConstString(ReserveTransactionType.Recoup))
+ .build("ReserveRecoupTransaction");
export const codecForReserveTransaction = (): Codec<ReserveTransaction> =>
buildCodecForUnion<ReserveTransaction>()
diff --git a/packages/taler-util/src/backupTypes.ts b/packages/taler-util/src/backupTypes.ts
index 41a9ce98e..b31a83831 100644
--- a/packages/taler-util/src/backupTypes.ts
+++ b/packages/taler-util/src/backupTypes.ts
@@ -54,7 +54,7 @@
* Imports.
*/
import { DenominationPubKey, UnblindedSignature } from "./talerTypes.js";
-import { Duration, Timestamp } from "./time.js";
+import { TalerProtocolDuration, TalerProtocolTimestamp } from "./time.js";
/**
* Type alias for strings that are to be treated like amounts.
@@ -120,7 +120,7 @@ export interface WalletBackupContentV1 {
* This timestamp should only be advanced if the content
* of the backup changes.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
/**
* Per-exchange data sorted by exchange master public key.
@@ -333,10 +333,10 @@ export interface BackupRecoupGroup {
/**
* Timestamp when the recoup was started.
*/
- timestamp_created: Timestamp;
+ timestamp_created: TalerProtocolTimestamp;
- timestamp_finish?: Timestamp;
- finish_clock?: Timestamp;
+ timestamp_finish?: TalerProtocolTimestamp;
+ finish_clock?: TalerProtocolTimestamp;
finish_is_failure?: boolean;
/**
@@ -486,14 +486,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: Timestamp | undefined;
+ timestamp_accepted: TalerProtocolTimestamp | undefined;
/**
* When was the tip first scanned by the wallet?
*/
- timestamp_created: Timestamp;
+ timestamp_created: TalerProtocolTimestamp;
- timestamp_finished?: Timestamp;
+ timestamp_finished?: TalerProtocolTimestamp;
finish_is_failure?: boolean;
/**
@@ -504,7 +504,7 @@ export interface BackupTip {
/**
* Timestamp, the tip can't be picked up anymore after this deadline.
*/
- timestamp_expiration: Timestamp;
+ timestamp_expiration: TalerProtocolTimestamp;
/**
* The exchange that will sign our coins, chosen by the merchant.
@@ -613,9 +613,9 @@ export interface BackupRefreshGroup {
*/
old_coins: BackupRefreshOldCoin[];
- timestamp_created: Timestamp;
+ timestamp_created: TalerProtocolTimestamp;
- timestamp_finish?: Timestamp;
+ timestamp_finish?: TalerProtocolTimestamp;
finish_is_failure?: boolean;
}
@@ -636,9 +636,9 @@ export interface BackupWithdrawalGroup {
* When was the withdrawal operation started started?
* Timestamp in milliseconds.
*/
- timestamp_created: Timestamp;
+ timestamp_created: TalerProtocolTimestamp;
- timestamp_finish?: Timestamp;
+ timestamp_finish?: TalerProtocolTimestamp;
finish_is_failure?: boolean;
/**
@@ -672,12 +672,12 @@ export interface BackupRefundItemCommon {
/**
* Execution time as claimed by the merchant
*/
- execution_time: Timestamp;
+ execution_time: TalerProtocolTimestamp;
/**
* Time when the wallet became aware of the refund.
*/
- obtained_time: Timestamp;
+ obtained_time: TalerProtocolTimestamp;
/**
* Amount refunded for the coin.
@@ -788,7 +788,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: Timestamp | undefined;
+ timestamp_first_successful_pay: TalerProtocolTimestamp | undefined;
/**
* Signature by the merchant confirming the payment.
@@ -799,7 +799,7 @@ export interface BackupPurchase {
* When was the purchase made?
* Refers to the time that the user accepted.
*/
- timestamp_accept: Timestamp;
+ timestamp_accept: TalerProtocolTimestamp;
/**
* Pending refunds for the purchase. A refund is pending
@@ -815,7 +815,7 @@ export interface BackupPurchase {
/**
* Continue querying the refund status until this deadline has expired.
*/
- auto_refund_deadline: Timestamp | undefined;
+ auto_refund_deadline: TalerProtocolTimestamp | undefined;
}
/**
@@ -857,22 +857,22 @@ export interface BackupDenomination {
/**
* Validity start date of the denomination.
*/
- stamp_start: Timestamp;
+ stamp_start: TalerProtocolTimestamp;
/**
* Date after which the currency can't be withdrawn anymore.
*/
- stamp_expire_withdraw: Timestamp;
+ stamp_expire_withdraw: TalerProtocolTimestamp;
/**
* Date after the denomination officially doesn't exist anymore.
*/
- stamp_expire_legal: Timestamp;
+ stamp_expire_legal: TalerProtocolTimestamp;
/**
* Data after which coins of this denomination can't be deposited anymore.
*/
- stamp_expire_deposit: Timestamp;
+ stamp_expire_deposit: TalerProtocolTimestamp;
/**
* Signature by the exchange's master key over the denomination
@@ -903,7 +903,7 @@ export interface BackupDenomination {
* The list issue date of the exchange "/keys" response
* that this denomination was last seen in.
*/
- list_issue_date: Timestamp;
+ list_issue_date: TalerProtocolTimestamp;
}
/**
@@ -923,14 +923,14 @@ export interface BackupReserve {
/**
* Time when the reserve was created.
*/
- timestamp_created: Timestamp;
+ timestamp_created: TalerProtocolTimestamp;
/**
* Timestamp of the last observed activity.
*
* Used to compute when to give up querying the exchange.
*/
- timestamp_last_activity: Timestamp;
+ timestamp_last_activity: TalerProtocolTimestamp;
/**
* Timestamp of when the reserve closed.
@@ -938,7 +938,7 @@ export interface BackupReserve {
* Note that the last activity can be after the closing time
* due to recouping.
*/
- timestamp_closed?: Timestamp;
+ timestamp_closed?: TalerProtocolTimestamp;
/**
* Wire information (as payto URI) for the bank account that
@@ -977,14 +977,14 @@ export interface BackupReserve {
/**
* Time when the information about this reserve was posted to the bank.
*/
- timestamp_reserve_info_posted: Timestamp | undefined;
+ timestamp_reserve_info_posted: TalerProtocolTimestamp | undefined;
/**
* Time when the reserve was confirmed by the bank.
*
* Set to undefined if not confirmed yet.
*/
- timestamp_bank_confirmed: Timestamp | undefined;
+ timestamp_bank_confirmed: TalerProtocolTimestamp | undefined;
};
/**
@@ -1033,12 +1033,12 @@ export interface BackupExchangeWireFee {
/**
* Start date of the fee.
*/
- start_stamp: Timestamp;
+ start_stamp: TalerProtocolTimestamp;
/**
* End date of the fee.
*/
- end_stamp: Timestamp;
+ end_stamp: TalerProtocolTimestamp;
/**
* Signature made by the exchange master key.
@@ -1050,9 +1050,9 @@ export interface BackupExchangeWireFee {
* Structure of one exchange signing key in the /keys response.
*/
export class BackupExchangeSignKey {
- stamp_start: Timestamp;
- stamp_expire: Timestamp;
- stamp_end: Timestamp;
+ stamp_start: TalerProtocolTimestamp;
+ stamp_expire: TalerProtocolTimestamp;
+ stamp_end: TalerProtocolTimestamp;
key: string;
master_sig: string;
}
@@ -1112,7 +1112,7 @@ export interface BackupExchange {
*
* Used to facilitate automatic merging.
*/
- update_clock: Timestamp;
+ update_clock: TalerProtocolTimestamp;
}
/**
@@ -1161,7 +1161,7 @@ export interface BackupExchangeDetails {
/**
* Closing delay of reserves.
*/
- reserve_closing_delay: Duration;
+ reserve_closing_delay: TalerProtocolDuration;
/**
* Signing keys we got from the exchange, can also contain
@@ -1187,7 +1187,7 @@ export interface BackupExchangeDetails {
/**
* Timestamp when the ToS has been accepted.
*/
- tos_accepted_timestamp: Timestamp | undefined;
+ tos_accepted_timestamp: TalerProtocolTimestamp | undefined;
}
export enum BackupProposalStatus {
@@ -1248,7 +1248,7 @@ export interface BackupProposal {
* Timestamp of when the record
* was created.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
/**
* Private key for the nonce.
diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts
index 4ccfffce0..b1bf6ab38 100644
--- a/packages/taler-util/src/talerTypes.ts
+++ b/packages/taler-util/src/talerTypes.ts
@@ -38,15 +38,14 @@ import {
codecForConstNumber,
buildCodecForUnion,
codecForConstString,
- codecForEither,
} from "./codec.js";
import {
- Timestamp,
codecForTimestamp,
- Duration,
codecForDuration,
+ TalerProtocolTimestamp,
+ TalerProtocolDuration,
} from "./time.js";
-import { Amounts, codecForAmountString } from "./amounts.js";
+import { codecForAmountString } from "./amounts.js";
import { strcmp } from "./helpers.js";
/**
@@ -86,24 +85,24 @@ export class ExchangeDenomination {
/**
* Start date from which withdraw is allowed.
*/
- stamp_start: Timestamp;
+ stamp_start: TalerProtocolTimestamp;
/**
* End date for withdrawing.
*/
- stamp_expire_withdraw: Timestamp;
+ stamp_expire_withdraw: TalerProtocolTimestamp;
/**
* Expiration date after which the exchange can forget about
* the currency.
*/
- stamp_expire_legal: Timestamp;
+ stamp_expire_legal: TalerProtocolTimestamp;
/**
* Date after which the coins of this denomination can't be
* deposited anymore.
*/
- stamp_expire_deposit: Timestamp;
+ stamp_expire_deposit: TalerProtocolTimestamp;
/**
* Signature over the denomination information by the exchange's master
@@ -394,7 +393,7 @@ export interface Product {
taxes?: Tax[];
// time indicating when this product should be delivered
- delivery_date?: Timestamp;
+ delivery_date?: TalerProtocolTimestamp;
}
export interface InternationalizedString {
@@ -413,7 +412,7 @@ export interface ContractTerms {
/**
* Hash of the merchant's wire details.
*/
- auto_refund?: Duration;
+ auto_refund?: TalerProtocolDuration;
/**
* Wire method the merchant wants to use.
@@ -445,7 +444,7 @@ export interface ContractTerms {
/**
* Deadline to pay for the contract.
*/
- pay_deadline: Timestamp;
+ pay_deadline: TalerProtocolTimestamp;
/**
* Maximum deposit fee covered by the merchant.
@@ -466,7 +465,7 @@ export interface ContractTerms {
* Time indicating when the order should be delivered.
* May be overwritten by individual products.
*/
- delivery_date?: Timestamp;
+ delivery_date?: TalerProtocolTimestamp;
/**
* Delivery location for (all!) products.
@@ -486,17 +485,17 @@ export interface ContractTerms {
/**
* Deadline for refunds.
*/
- refund_deadline: Timestamp;
+ refund_deadline: TalerProtocolTimestamp;
/**
* Deadline for the wire transfer.
*/
- wire_transfer_deadline: Timestamp;
+ wire_transfer_deadline: TalerProtocolTimestamp;
/**
* Time when the contract was generated by the merchant.
*/
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
/**
* Order id to uniquely identify the purchase within
@@ -700,9 +699,9 @@ export class Recoup {
* Structure of one exchange signing key in the /keys response.
*/
export class ExchangeSignKeyJson {
- stamp_start: Timestamp;
- stamp_expire: Timestamp;
- stamp_end: Timestamp;
+ stamp_start: TalerProtocolTimestamp;
+ stamp_expire: TalerProtocolTimestamp;
+ stamp_end: TalerProtocolTimestamp;
key: EddsaPublicKeyString;
master_sig: EddsaSignatureString;
}
@@ -729,7 +728,7 @@ export class ExchangeKeysJson {
/**
* Timestamp when this response was issued.
*/
- list_issue_date: Timestamp;
+ list_issue_date: TalerProtocolTimestamp;
/**
* List of revoked denominations.
@@ -747,7 +746,7 @@ export class ExchangeKeysJson {
*/
version: string;
- reserve_closing_delay: Duration;
+ reserve_closing_delay: TalerProtocolDuration;
}
/**
@@ -774,12 +773,12 @@ export class WireFeesJson {
/**
* Date from which the fee applies.
*/
- start_date: Timestamp;
+ start_date: TalerProtocolTimestamp;
/**
* Data after which the fee doesn't apply anymore.
*/
- end_date: Timestamp;
+ end_date: TalerProtocolTimestamp;
}
export interface AccountInfo {
@@ -850,7 +849,7 @@ export class TipPickupGetResponse {
exchange_url: string;
- expiration: Timestamp;
+ expiration: TalerProtocolTimestamp;
}
export enum DenomKeyType {
@@ -1067,7 +1066,7 @@ export interface MerchantCoinRefundSuccessStatus {
// to the customer.
refund_amount: AmountString;
- execution_time: Timestamp;
+ execution_time: TalerProtocolTimestamp;
}
export interface MerchantCoinRefundFailureStatus {
@@ -1092,7 +1091,7 @@ export interface MerchantCoinRefundFailureStatus {
// to the customer.
refund_amount: AmountString;
- execution_time: Timestamp;
+ execution_time: TalerProtocolTimestamp;
}
export interface MerchantOrderStatusUnpaid {
@@ -1733,7 +1732,7 @@ export interface DepositSuccess {
transaction_base_url?: string;
// timestamp when the deposit was received by the exchange.
- exchange_timestamp: Timestamp;
+ exchange_timestamp: TalerProtocolTimestamp;
// the EdDSA signature of TALER_DepositConfirmationPS using a current
// signing key of the exchange affirming the successful
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 9f9571019..43cb7ad4d 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -23,13 +23,41 @@
*/
import { Codec, renderContext, Context } from "./codec.js";
-export interface Timestamp {
+export interface AbsoluteTime {
/**
* Timestamp in milliseconds.
*/
readonly t_ms: number | "never";
}
+export interface TalerProtocolTimestamp {
+ readonly t_s: number | "never";
+}
+
+export namespace TalerProtocolTimestamp {
+ export function now(): TalerProtocolTimestamp {
+ return AbsoluteTime.toTimestamp(AbsoluteTime.now());
+ }
+
+ export function zero(): TalerProtocolTimestamp {
+ return {
+ t_s: 0,
+ };
+ }
+
+ export function never(): TalerProtocolTimestamp {
+ return {
+ t_s: "never",
+ };
+ }
+
+ export function fromSeconds(s: number): TalerProtocolTimestamp {
+ return {
+ t_s: s,
+ };
+ }
+}
+
export interface Duration {
/**
* Duration in milliseconds.
@@ -37,40 +65,32 @@ export interface Duration {
readonly d_ms: number | "forever";
}
+export interface TalerProtocolDuration {
+ readonly d_us: number | "forever";
+}
+
let timeshift = 0;
export function setDangerousTimetravel(dt: number): void {
timeshift = dt;
}
-export function getTimestampNow(): Timestamp {
- return {
- t_ms: new Date().getTime() + timeshift,
- };
-}
-
-export function isTimestampExpired(t: Timestamp) {
- return timestampCmp(t, getTimestampNow()) <= 0;
-}
-
-export function getDurationRemaining(
- deadline: Timestamp,
- now = getTimestampNow(),
-): Duration {
- if (deadline.t_ms === "never") {
- return { d_ms: "forever" };
- }
- if (now.t_ms === "never") {
- throw Error("invalid argument for 'now'");
- }
- if (deadline.t_ms < now.t_ms) {
- return { d_ms: 0 };
- }
- return { d_ms: deadline.t_ms - now.t_ms };
-}
-
export namespace Duration {
- export const getRemaining = getDurationRemaining;
+ export function getRemaining(
+ deadline: AbsoluteTime,
+ now = AbsoluteTime.now(),
+ ): Duration {
+ if (deadline.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ if (now.t_ms === "never") {
+ throw Error("invalid argument for 'now'");
+ }
+ if (deadline.t_ms < now.t_ms) {
+ return { d_ms: 0 };
+ }
+ return { d_ms: deadline.t_ms - now.t_ms };
+ }
export function toIntegerYears(d: Duration): number {
if (typeof d.d_ms !== "number") {
throw Error("infinite duration");
@@ -81,33 +101,152 @@ export namespace Duration {
export function getForever(): Duration {
return { d_ms: "forever" };
}
+ export function fromTalerProtocolDuration(
+ d: TalerProtocolDuration,
+ ): Duration {
+ if (d.d_us === "forever") {
+ return {
+ d_ms: "forever",
+ };
+ }
+ return {
+ d_ms: d.d_us / 1000,
+ };
+ }
}
-export namespace Timestamp {
- export const now = getTimestampNow;
- export const min = timestampMin;
- export const isExpired = isTimestampExpired;
- export const truncateToSecond = timestampTruncateToSecond;
-}
+export namespace AbsoluteTime {
+ export function now(): AbsoluteTime {
+ return {
+ t_ms: new Date().getTime() + timeshift,
+ };
+ }
-export function timestampMin(t1: Timestamp, t2: Timestamp): Timestamp {
- if (t1.t_ms === "never") {
- return { t_ms: t2.t_ms };
+ export function never(): AbsoluteTime {
+ return {
+ t_ms: "never",
+ };
}
- if (t2.t_ms === "never") {
- return { t_ms: t2.t_ms };
+
+ export function cmp(t1: AbsoluteTime, t2: AbsoluteTime): number {
+ if (t1.t_ms === "never") {
+ if (t2.t_ms === "never") {
+ return 0;
+ }
+ return 1;
+ }
+ if (t2.t_ms === "never") {
+ return -1;
+ }
+ if (t1.t_ms == t2.t_ms) {
+ return 0;
+ }
+ if (t1.t_ms > t2.t_ms) {
+ return 1;
+ }
+ return -1;
+ }
+
+ export function min(t1: AbsoluteTime, t2: AbsoluteTime): AbsoluteTime {
+ if (t1.t_ms === "never") {
+ return { t_ms: t2.t_ms };
+ }
+ if (t2.t_ms === "never") {
+ return { t_ms: t2.t_ms };
+ }
+ return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
}
- return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
-}
-export function timestampMax(t1: Timestamp, t2: Timestamp): Timestamp {
- if (t1.t_ms === "never") {
- return { t_ms: "never" };
+ export function max(t1: AbsoluteTime, t2: AbsoluteTime): AbsoluteTime {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ if (t2.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ return { t_ms: Math.max(t1.t_ms, t2.t_ms) };
}
- if (t2.t_ms === "never") {
- return { t_ms: "never" };
+
+ export function difference(t1: AbsoluteTime, t2: AbsoluteTime): Duration {
+ if (t1.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ if (t2.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ return { d_ms: Math.abs(t1.t_ms - t2.t_ms) };
+ }
+
+ export function isExpired(t: AbsoluteTime) {
+ return cmp(t, now()) <= 0;
+ }
+
+ export function fromTimestamp(t: TalerProtocolTimestamp): AbsoluteTime {
+ if (t.t_s === "never") {
+ return { t_ms: "never" };
+ }
+ return {
+ t_ms: t.t_s * 1000,
+ };
+ }
+
+ export function toTimestamp(at: AbsoluteTime): TalerProtocolTimestamp {
+ if (at.t_ms === "never") {
+ return { t_s: "never" };
+ }
+ return {
+ t_s: Math.floor(at.t_ms / 1000),
+ };
+ }
+
+ export function isBetween(
+ t: AbsoluteTime,
+ start: AbsoluteTime,
+ end: AbsoluteTime,
+ ): boolean {
+ if (cmp(t, start) < 0) {
+ return false;
+ }
+ if (cmp(t, end) > 0) {
+ return false;
+ }
+ return true;
+ }
+
+ export function toIsoString(t: AbsoluteTime): string {
+ if (t.t_ms === "never") {
+ return "<never>";
+ } else {
+ return new Date(t.t_ms).toISOString();
+ }
+ }
+
+ export function addDuration(t1: AbsoluteTime, d: Duration): AbsoluteTime {
+ if (t1.t_ms === "never" || d.d_ms === "forever") {
+ return { t_ms: "never" };
+ }
+ return { t_ms: t1.t_ms + d.d_ms };
+ }
+
+ export function subtractDuraction(
+ t1: AbsoluteTime,
+ d: Duration,
+ ): AbsoluteTime {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ if (d.d_ms === "forever") {
+ return { t_ms: 0 };
+ }
+ return { t_ms: Math.max(0, t1.t_ms - d.d_ms) };
+ }
+
+ export function stringify(t: AbsoluteTime): string {
+ if (t.t_ms === "never") {
+ return "never";
+ }
+ return new Date(t.t_ms).toISOString();
}
- return { t_ms: Math.max(t1.t_ms, t2.t_ms) };
}
const SECONDS = 1000;
@@ -135,19 +274,6 @@ export function durationFromSpec(spec: {
return { d_ms };
}
-/**
- * Truncate a timestamp so that that it represents a multiple
- * of seconds. The timestamp is always rounded down.
- */
-export function timestampTruncateToSecond(t1: Timestamp): Timestamp {
- if (t1.t_ms === "never") {
- return { t_ms: "never" };
- }
- return {
- t_ms: Math.floor(t1.t_ms / 1000) * 1000,
- };
-}
-
export function durationMin(d1: Duration, d2: Duration): Duration {
if (d1.d_ms === "forever") {
return { d_ms: d2.d_ms };
@@ -182,111 +308,33 @@ export function durationAdd(d1: Duration, d2: Duration): Duration {
return { d_ms: d1.d_ms + d2.d_ms };
}
-export function timestampCmp(t1: Timestamp, t2: Timestamp): number {
- if (t1.t_ms === "never") {
- if (t2.t_ms === "never") {
- return 0;
- }
- return 1;
- }
- if (t2.t_ms === "never") {
- return -1;
- }
- if (t1.t_ms == t2.t_ms) {
- return 0;
- }
- if (t1.t_ms > t2.t_ms) {
- return 1;
- }
- return -1;
-}
-
-export function timestampAddDuration(t1: Timestamp, d: Duration): Timestamp {
- if (t1.t_ms === "never" || d.d_ms === "forever") {
- return { t_ms: "never" };
- }
- return { t_ms: t1.t_ms + d.d_ms };
-}
-
-export function timestampSubtractDuraction(
- t1: Timestamp,
- d: Duration,
-): Timestamp {
- if (t1.t_ms === "never") {
- return { t_ms: "never" };
- }
- if (d.d_ms === "forever") {
- return { t_ms: 0 };
- }
- return { t_ms: Math.max(0, t1.t_ms - d.d_ms) };
-}
-
-export function stringifyTimestamp(t: Timestamp): string {
- if (t.t_ms === "never") {
- return "never";
- }
- return new Date(t.t_ms).toISOString();
-}
-
-export function timestampDifference(t1: Timestamp, t2: Timestamp): Duration {
- if (t1.t_ms === "never") {
- return { d_ms: "forever" };
- }
- if (t2.t_ms === "never") {
- return { d_ms: "forever" };
- }
- return { d_ms: Math.abs(t1.t_ms - t2.t_ms) };
-}
-
-export function timestampToIsoString(t: Timestamp): string {
- if (t.t_ms === "never") {
- return "<never>";
- } else {
- return new Date(t.t_ms).toISOString();
- }
-}
-
-export function timestampIsBetween(
- t: Timestamp,
- start: Timestamp,
- end: Timestamp,
-): boolean {
- if (timestampCmp(t, start) < 0) {
- return false;
- }
- if (timestampCmp(t, end) > 0) {
- return false;
- }
- return true;
-}
-
-export const codecForTimestamp: Codec<Timestamp> = {
- decode(x: any, c?: Context): Timestamp {
- const t_ms = x.t_ms;
- if (typeof t_ms === "string") {
- if (t_ms === "never") {
- return { t_ms: "never" };
+export const codecForTimestamp: Codec<TalerProtocolTimestamp> = {
+ decode(x: any, c?: Context): TalerProtocolTimestamp {
+ const t_s = x.t_s;
+ if (typeof t_s === "string") {
+ if (t_s === "never") {
+ return { t_s: "never" };
}
throw Error(`expected timestamp at ${renderContext(c)}`);
}
- if (typeof t_ms === "number") {
- return { t_ms };
+ if (typeof t_s === "number") {
+ return { t_s };
}
throw Error(`expected timestamp at ${renderContext(c)}`);
},
};
-export const codecForDuration: Codec<Duration> = {
- decode(x: any, c?: Context): Duration {
- const d_ms = x.d_ms;
- if (typeof d_ms === "string") {
- if (d_ms === "forever") {
- return { d_ms: "forever" };
+export const codecForDuration: Codec<TalerProtocolDuration> = {
+ decode(x: any, c?: Context): TalerProtocolDuration {
+ const d_us = x.d_us;
+ if (typeof d_us === "string") {
+ if (d_us === "forever") {
+ return { d_us: "forever" };
}
throw Error(`expected duration at ${renderContext(c)}`);
}
- if (typeof d_ms === "number") {
- return { d_ms };
+ if (typeof d_us === "number") {
+ return { d_us };
}
throw Error(`expected duration at ${renderContext(c)}`);
},
diff --git a/packages/taler-util/src/transactionsTypes.ts b/packages/taler-util/src/transactionsTypes.ts
index e780ca411..bccbc7737 100644
--- a/packages/taler-util/src/transactionsTypes.ts
+++ b/packages/taler-util/src/transactionsTypes.ts
@@ -24,7 +24,7 @@
/**
* Imports.
*/
-import { Timestamp } from "./time.js";
+import { TalerProtocolTimestamp } from "./time.js";
import {
AmountString,
Product,
@@ -73,7 +73,7 @@ export interface TransactionCommon {
type: TransactionType;
// main timestamp of the transaction
- timestamp: Timestamp;
+ timestamp: TalerProtocolTimestamp;
// true if the transaction is still pending, false otherwise
// If a transaction is not longer pending, its timestamp will be updated,
diff --git a/packages/taler-util/src/types-test.ts b/packages/taler-util/src/types-test.ts
index 6998bb5fb..e8af13119 100644
--- a/packages/taler-util/src/types-test.ts
+++ b/packages/taler-util/src/types-test.ts
@@ -29,13 +29,13 @@ test("contract terms validation", (t) => {
merchant_pub: "12345",
merchant: { name: "Foo" },
order_id: "test_order",
- pay_deadline: { t_ms: 42 },
- wire_transfer_deadline: { t_ms: 42 },
+ pay_deadline: { t_s: 42 },
+ wire_transfer_deadline: { t_s: 42 },
merchant_base_url: "https://example.com/pay",
products: [],
- refund_deadline: { t_ms: 42 },
+ refund_deadline: { t_s: 42 },
summary: "hello",
- timestamp: { t_ms: 42 },
+ timestamp: { t_s: 42 },
wire_method: "test",
};
@@ -71,13 +71,13 @@ test("contract terms validation (locations)", (t) => {
},
},
order_id: "test_order",
- pay_deadline: { t_ms: 42 },
- wire_transfer_deadline: { t_ms: 42 },
+ pay_deadline: { t_s: 42 },
+ wire_transfer_deadline: { t_s: 42 },
merchant_base_url: "https://example.com/pay",
products: [],
- refund_deadline: { t_ms: 42 },
+ refund_deadline: { t_s: 42 },
summary: "hello",
- timestamp: { t_ms: 42 },
+ timestamp: { t_s: 42 },
wire_method: "test",
delivery_location: {
country: "FR",
diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts
index 9a3f1f8f8..3c4fa96c7 100644
--- a/packages/taler-util/src/walletTypes.ts
+++ b/packages/taler-util/src/walletTypes.ts
@@ -32,7 +32,11 @@ import {
codecForAmountJson,
codecForAmountString,
} from "./amounts.js";
-import { Timestamp, codecForTimestamp } from "./time.js";
+import {
+ AbsoluteTime,
+ codecForTimestamp,
+ TalerProtocolTimestamp,
+} from "./time.js";
import {
buildCodecForObject,
codecForString,
@@ -299,7 +303,7 @@ export interface PrepareTipResult {
* Time when the tip will expire. After it expired, it can't be picked
* up anymore.
*/
- expirationTimestamp: Timestamp;
+ expirationTimestamp: TalerProtocolTimestamp;
}
export const codecForPrepareTipResult = (): Codec<PrepareTipResult> =>
@@ -460,7 +464,7 @@ export interface TalerErrorDetails {
/**
* Minimal information needed about a planchet for unblinding a signature.
- *
+ *
* Can be a withdrawal/tipping/refresh planchet.
*/
export interface PlanchetUnblindInfo {
@@ -527,8 +531,8 @@ export interface DepositInfo {
coinPub: string;
coinPriv: string;
spendAmount: AmountJson;
- timestamp: Timestamp;
- refundDeadline: Timestamp;
+ timestamp: TalerProtocolTimestamp;
+ refundDeadline: TalerProtocolTimestamp;
merchantPub: string;
feeDeposit: AmountJson;
wireInfoHash: string;