From 4159367d8c04b96a05da8a5ded043f8296a83174 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 6 Dec 2019 02:52:16 +0100 Subject: pending ops / history / notification tweaks --- src/wallet-impl/history.ts | 307 ++++++++++++++++++++++++++------------------- 1 file changed, 177 insertions(+), 130 deletions(-) (limited to 'src/wallet-impl/history.ts') diff --git a/src/wallet-impl/history.ts b/src/wallet-impl/history.ts index 23887e895..99e51c8de 100644 --- a/src/wallet-impl/history.ts +++ b/src/wallet-impl/history.ts @@ -14,11 +14,11 @@ GNU Taler; see the file COPYING. If not, see */ - /** - * Imports. - */ +/** + * Imports. + */ import { HistoryQuery, HistoryEvent } from "../walletTypes"; -import { oneShotIter } from "../util/query"; +import { oneShotIter, runWithReadTransaction } from "../util/query"; import { InternalWalletState } from "./state"; import { Stores, TipRecord } from "../dbTypes"; import * as Amounts from "../util/amounts"; @@ -34,139 +34,186 @@ export async function getHistory( const history: HistoryEvent[] = []; // FIXME: do pagination instead of generating the full history - // We uniquely identify history rows via their timestamp. // This works as timestamps are guaranteed to be monotonically // increasing even - /* - const proposals = await oneShotIter(ws.db, Stores.proposals).toArray(); - for (const p of proposals) { - history.push({ - detail: { - contractTermsHash: p.contractTermsHash, - merchantName: p.contractTerms.merchant.name, - }, - timestamp: p.timestamp, - type: "claim-order", - explicit: false, - }); - } - */ - - const withdrawals = await oneShotIter( + await runWithReadTransaction( ws.db, - Stores.withdrawalSession, - ).toArray(); - for (const w of withdrawals) { - history.push({ - detail: { - withdrawalAmount: w.rawWithdrawalAmount, - }, - timestamp: w.startTimestamp, - type: "withdraw", - explicit: false, - }); - } - - const purchases = await oneShotIter(ws.db, Stores.purchases).toArray(); - for (const p of purchases) { - history.push({ - detail: { - amount: p.contractTerms.amount, - contractTermsHash: p.contractTermsHash, - fulfillmentUrl: p.contractTerms.fulfillment_url, - merchantName: p.contractTerms.merchant.name, - }, - timestamp: p.acceptTimestamp, - type: "pay", - explicit: false, - }); - if (p.lastRefundStatusTimestamp) { - const contractAmount = Amounts.parseOrThrow(p.contractTerms.amount); - const amountsPending = Object.keys(p.refundsPending).map(x => - Amounts.parseOrThrow(p.refundsPending[x].refund_amount), - ); - const amountsDone = Object.keys(p.refundsDone).map(x => - Amounts.parseOrThrow(p.refundsDone[x].refund_amount), - ); - const amounts: AmountJson[] = amountsPending.concat(amountsDone); - const amount = Amounts.add( - Amounts.getZero(contractAmount.currency), - ...amounts, - ).amount; - - history.push({ - detail: { - contractTermsHash: p.contractTermsHash, - fulfillmentUrl: p.contractTerms.fulfillment_url, - merchantName: p.contractTerms.merchant.name, - refundAmount: amount, - }, - timestamp: p.lastRefundStatusTimestamp, - type: "refund", - explicit: false, + [ + Stores.currencies, + Stores.coins, + Stores.denominations, + Stores.exchanges, + Stores.proposals, + Stores.purchases, + Stores.refresh, + Stores.reserves, + Stores.tips, + Stores.withdrawalSession, + ], + async tx => { + await tx.iter(Stores.proposals).forEach(p => { + history.push({ + detail: {}, + timestamp: p.timestamp, + type: "claim-order", + explicit: false, + }); + }); + + await tx.iter(Stores.withdrawalSession).forEach(w => { + history.push({ + detail: { + withdrawalAmount: w.rawWithdrawalAmount, + }, + timestamp: w.startTimestamp, + type: "withdraw-started", + explicit: false, + }); + if (w.finishTimestamp) { + history.push({ + detail: { + withdrawalAmount: w.rawWithdrawalAmount, + }, + timestamp: w.finishTimestamp, + type: "withdraw-finished", + explicit: false, + }); + } + }); + + await tx.iter(Stores.purchases).forEach(p => { + history.push({ + detail: { + amount: p.contractTerms.amount, + contractTermsHash: p.contractTermsHash, + fulfillmentUrl: p.contractTerms.fulfillment_url, + merchantName: p.contractTerms.merchant.name, + }, + timestamp: p.acceptTimestamp, + type: "pay-started", + explicit: false, + }); + if (p.firstSuccessfulPayTimestamp) { + history.push({ + detail: { + amount: p.contractTerms.amount, + contractTermsHash: p.contractTermsHash, + fulfillmentUrl: p.contractTerms.fulfillment_url, + merchantName: p.contractTerms.merchant.name, + }, + timestamp: p.firstSuccessfulPayTimestamp, + type: "pay-finished", + explicit: false, + }); + } + if (p.lastRefundStatusTimestamp) { + const contractAmount = Amounts.parseOrThrow(p.contractTerms.amount); + const amountsPending = Object.keys(p.refundsPending).map(x => + Amounts.parseOrThrow(p.refundsPending[x].refund_amount), + ); + const amountsDone = Object.keys(p.refundsDone).map(x => + Amounts.parseOrThrow(p.refundsDone[x].refund_amount), + ); + const amounts: AmountJson[] = amountsPending.concat(amountsDone); + const amount = Amounts.add( + Amounts.getZero(contractAmount.currency), + ...amounts, + ).amount; + + history.push({ + detail: { + contractTermsHash: p.contractTermsHash, + fulfillmentUrl: p.contractTerms.fulfillment_url, + merchantName: p.contractTerms.merchant.name, + refundAmount: amount, + }, + timestamp: p.lastRefundStatusTimestamp, + type: "refund", + explicit: false, + }); + } }); - } - } - - const reserves = await oneShotIter(ws.db, Stores.reserves).toArray(); - - for (const r of reserves) { - const reserveType = r.bankWithdrawStatusUrl ? "taler-bank" : "manual"; - history.push({ - detail: { - exchangeBaseUrl: r.exchangeBaseUrl, - requestedAmount: Amounts.toString(r.initiallyRequestedAmount), - reservePub: r.reservePub, - reserveType, - bankWithdrawStatusUrl: r.bankWithdrawStatusUrl, - }, - timestamp: r.created, - type: "reserve-created", - explicit: false, - }); - if (r.timestampConfirmed) { - history.push({ - detail: { - exchangeBaseUrl: r.exchangeBaseUrl, - requestedAmount: Amounts.toString(r.initiallyRequestedAmount), - reservePub: r.reservePub, - reserveType, - bankWithdrawStatusUrl: r.bankWithdrawStatusUrl, - }, - timestamp: r.created, - type: "reserve-confirmed", - explicit: false, + + await tx.iter(Stores.reserves).forEach(r => { + const reserveType = r.bankWithdrawStatusUrl ? "taler-bank" : "manual"; + history.push({ + detail: { + exchangeBaseUrl: r.exchangeBaseUrl, + requestedAmount: Amounts.toString(r.initiallyRequestedAmount), + reservePub: r.reservePub, + reserveType, + bankWithdrawStatusUrl: r.bankWithdrawStatusUrl, + }, + timestamp: r.created, + type: "reserve-created", + explicit: false, + }); + if (r.timestampConfirmed) { + history.push({ + detail: { + exchangeBaseUrl: r.exchangeBaseUrl, + requestedAmount: Amounts.toString(r.initiallyRequestedAmount), + reservePub: r.reservePub, + reserveType, + bankWithdrawStatusUrl: r.bankWithdrawStatusUrl, + }, + timestamp: r.created, + type: "reserve-confirmed", + explicit: false, + }); + } + }); + + await tx.iter(Stores.tips).forEach(tip => { + history.push({ + detail: { + accepted: tip.accepted, + amount: tip.amount, + merchantBaseUrl: tip.merchantBaseUrl, + tipId: tip.merchantTipId, + }, + timestamp: tip.createdTimestamp, + explicit: false, + type: "tip", + }); + }); + + await tx.iter(Stores.exchanges).forEach(exchange => { + history.push({ + type: "exchange-added", + explicit: false, + timestamp: exchange.timestampAdded, + detail: { + exchangeBaseUrl: exchange.baseUrl, + }, + }); + }); + + await tx.iter(Stores.refresh).forEach((r) => { + history.push({ + type: "refresh-started", + explicit: false, + timestamp: r.created, + detail: { + refreshSessionId: r.refreshSessionId, + }, + }); + if (r.finishedTimestamp) { + history.push({ + type: "refresh-finished", + explicit: false, + timestamp: r.finishedTimestamp, + detail: { + refreshSessionId: r.refreshSessionId, + }, + }); + } + }); - } - } - - const tips: TipRecord[] = await oneShotIter(ws.db, Stores.tips).toArray(); - for (const tip of tips) { - history.push({ - detail: { - accepted: tip.accepted, - amount: tip.amount, - merchantBaseUrl: tip.merchantBaseUrl, - tipId: tip.merchantTipId, - }, - timestamp: tip.createdTimestamp, - explicit: false, - type: "tip", - }); - } - - await oneShotIter(ws.db, Stores.exchanges).forEach(exchange => { - history.push({ - type: "exchange-added", - explicit: false, - timestamp: exchange.timestampAdded, - detail: { - exchangeBaseUrl: exchange.baseUrl, - }, - }); - }); + }, + ); history.sort((h1, h2) => Math.sign(h1.timestamp.t_ms - h2.timestamp.t_ms)); -- cgit v1.2.3