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