aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/headless/integrationtest.ts9
-rw-r--r--src/headless/taler-wallet-cli.ts42
-rw-r--r--src/operations/pending.ts2
-rw-r--r--src/types/pending.ts12
-rw-r--r--src/webex/messages.ts5
-rw-r--r--src/webex/pages/popup.tsx390
-rw-r--r--src/webex/wxBackend.ts4
7 files changed, 31 insertions, 433 deletions
diff --git a/src/headless/integrationtest.ts b/src/headless/integrationtest.ts
index db96d57c4..51e93f30b 100644
--- a/src/headless/integrationtest.ts
+++ b/src/headless/integrationtest.ts
@@ -184,13 +184,6 @@ export async function runIntegrationTest(
);
await myWallet.runUntilDone();
-
- const history = await myWallet.getHistory({ extraDebug: true });
-
- console.log(
- "history after integration test:",
- JSON.stringify(history, undefined, 2),
- );
}
export async function runIntegrationTestBasic(
@@ -327,8 +320,6 @@ export async function runIntegrationTestBasic(
await myWallet.runUntilDone();
- const history = await myWallet.getHistory({ extraDebug: true });
-
console.log(
"history after integration test:",
JSON.stringify(history, undefined, 2),
diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts
index b8ae84d72..0357a10fe 100644
--- a/src/headless/taler-wallet-cli.ts
+++ b/src/headless/taler-wallet-cli.ts
@@ -39,6 +39,7 @@ import { makeCodecForList, codecForString } from "../util/codec";
import { NodeHttpLib } from "./NodeHttpLib";
import * as nacl from "../crypto/primitives/nacl-fast";
import { addPaytoQueryParams } from "../util/payto";
+import { handleCoreApiRequest } from "../walletCoreApiHandler";
const logger = new Logger("taler-wallet-cli.ts");
@@ -198,33 +199,26 @@ walletCli
});
walletCli
- .subcommand("history", "history", { help: "Show wallet event history." })
- .flag("json", ["--json"], {
- default: false,
- })
- .maybeOption("from", ["--from"], clk.STRING)
- .maybeOption("to", ["--to"], clk.STRING)
- .maybeOption("limit", ["--limit"], clk.STRING)
- .maybeOption("contEvt", ["--continue-with"], clk.STRING)
- .flag("extraDebug", ["--extra-debug"])
+ .subcommand("api", "balance", { help: "Call the wallet-core API directly." })
+ .requiredArgument("operation", clk.STRING)
+ .requiredArgument("request", clk.STRING)
.action(async (args) => {
await withWallet(args, async (wallet) => {
- const history = await wallet.getHistory({
- extraDebug: args.history.extraDebug,
- });
- if (args.history.json) {
- console.log(JSON.stringify(history, undefined, 2));
- } else {
- for (const h of history.history) {
- console.log(
- `event at ${new Date(h.timestamp.t_ms).toISOString()} with type ${
- h.type
- }:`,
- );
- console.log(JSON.stringify(h, undefined, 2));
- console.log();
- }
+ let requestJson;
+ try {
+ requestJson = JSON.parse(args.api.operation);
+ } catch (e) {
+ console.error("malformed request");
+ process.exit(1);
+ return;
}
+ const resp = await handleCoreApiRequest(
+ wallet,
+ args.api.operation,
+ 1,
+ requestJson,
+ );
+ console.log(JSON.stringify(resp, undefined, 2));
});
});
diff --git a/src/operations/pending.ts b/src/operations/pending.ts
index e610d42ef..acad5e634 100644
--- a/src/operations/pending.ts
+++ b/src/operations/pending.ts
@@ -27,6 +27,7 @@ import {
PendingOperationsResponse,
PendingOperationType,
ExchangeUpdateOperationStage,
+ ReserveType,
} from "../types/pending";
import {
Duration,
@@ -38,7 +39,6 @@ import {
import { TransactionHandle } from "../util/query";
import { InternalWalletState } from "./state";
import { getBalancesInsideTransaction } from "./balance";
-import { ReserveType } from "../types/history";
function updateRetryDelay(
oldDelay: Duration,
diff --git a/src/types/pending.ts b/src/types/pending.ts
index 8a1e84362..e6c879992 100644
--- a/src/types/pending.ts
+++ b/src/types/pending.ts
@@ -24,7 +24,6 @@
import { OperationErrorDetails, WalletBalance } from "./walletTypes";
import { WithdrawalSource, RetryInfo, ReserveRecordStatus } from "./dbTypes";
import { Timestamp, Duration } from "../util/time";
-import { ReserveType } from "./history";
export const enum PendingOperationType {
Bug = "bug",
@@ -91,6 +90,17 @@ export const enum ExchangeUpdateOperationStage {
FinalizeUpdate = "finalize-update",
}
+export const enum ReserveType {
+ /**
+ * Manually created.
+ */
+ Manual = "manual",
+ /**
+ * Withdrawn from a bank that has "tight" Taler integration
+ */
+ TalerBankWithdraw = "taler-bank-withdraw",
+}
+
/**
* Status of processing a reserve.
*
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index fd9fe0347..5f63697c1 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -25,7 +25,6 @@ import * as dbTypes from "../types/dbTypes";
import * as walletTypes from "../types/walletTypes";
import { UpgradeResponse } from "./wxApi";
-import { HistoryEvent } from "../types/history";
/**
* Message type information.
@@ -61,10 +60,6 @@ export interface MessageMap {
request: { baseUrl: string };
response: dbTypes.ExchangeRecord;
};
- "get-history": {
- request: {};
- response: HistoryEvent[];
- };
"get-coins": {
request: { exchangeBaseUrl: string };
response: any;
diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx
index 875bbcb5c..e4eea4d9e 100644
--- a/src/webex/pages/popup.tsx
+++ b/src/webex/pages/popup.tsx
@@ -35,7 +35,6 @@ import { abbrev, renderAmount, PageLink } from "../renderHtml";
import * as wxApi from "../wxApi";
import React, { Fragment, useState, useEffect } from "react";
-import { HistoryEvent } from "../../types/history";
import moment from "moment";
import { Timestamp } from "../../util/time";
@@ -315,311 +314,9 @@ function formatAndCapitalize(text: string): string {
return text;
}
-type HistoryItemProps = {
- title?: string | JSX.Element;
- text?: string | JSX.Element;
- small?: string | JSX.Element;
- amount?: string | AmountJson;
- fees?: string | AmountJson;
- invalid?: string | AmountJson;
- icon?: string;
- timestamp: Timestamp;
- negative?: boolean;
-};
-
-function HistoryItem({
- title,
- text,
- small,
- amount,
- fees,
- invalid,
- timestamp,
- icon,
- negative = false,
-}: HistoryItemProps): JSX.Element {
- function formatDate(timestamp: number | "never"): string | null {
- if (timestamp !== "never") {
- const itemDate = moment(timestamp);
- if (itemDate.isBetween(moment().subtract(2, "days"), moment())) {
- return itemDate.fromNow();
- }
- return itemDate.format("lll");
- }
- return null;
- }
-
- let invalidElement, amountElement, feesElement;
-
- if (amount) {
- amountElement = renderAmount(amount);
- }
-
- if (fees) {
- fees = typeof fees === "string" ? Amounts.parse(fees) : fees;
- if (fees && Amounts.isNonZero(fees)) {
- feesElement = renderAmount(fees);
- }
- }
-
- if (invalid) {
- invalid = typeof invalid === "string" ? Amounts.parse(invalid) : invalid;
- if (invalid && Amounts.isNonZero(invalid)) {
- invalidElement = renderAmount(invalid);
- }
- }
-
- return (
- <div className="historyItem">
- {icon ? <Icon l={icon} /> : null}
- <div className="historyContent">
- {title ? <div className={"historyTitle"}>{title}</div> : null}
- {text ? <div className={"historyText"}>{text}</div> : null}
- {small ? <div className={"historySmall"}>{small}</div> : null}
- </div>
- <div className={"historyLeft"}>
- <div className={"historyAmount"}>
- {amountElement ? (
- <div className={`${negative ? "negative" : "positive"}`}>
- {amountElement}
- </div>
- ) : null}
- {invalidElement ? (
- <div className={"secondary"}>
- {i18n.str`Invalid `}{" "}
- <span className={"negative"}>{invalidElement}</span>
- </div>
- ) : null}
- {feesElement ? (
- <div className={"secondary"}>
- {i18n.str`Fees `}{" "}
- <span className={"negative"}>{feesElement}</span>
- </div>
- ) : null}
- </div>
- <div className="historyDate">{formatDate(timestamp.t_ms)}</div>
- </div>
- </div>
- );
-}
-
-function amountDiff(
- total: string | Amounts.AmountJson,
- partial: string | Amounts.AmountJson,
-): Amounts.AmountJson | string {
- const a = typeof total === "string" ? Amounts.parse(total) : total;
- const b = typeof partial === "string" ? Amounts.parse(partial) : partial;
- if (a && b) {
- return Amounts.sub(a, b).amount;
- } else {
- return total;
- }
-}
-
-function parseSummary(summary: string): { item: string; merchant: string } {
- const parsed = summary.split(/: (.+)/);
- return {
- merchant: parsed[0],
- item: parsed[1],
- };
-}
-
-function formatHistoryItem(historyItem: HistoryEvent): JSX.Element {
- switch (historyItem.type) {
- case "refreshed": {
- return (
- <HistoryItem
- timestamp={historyItem.timestamp}
- small={i18n.str`Refresh sessions has completed`}
- fees={amountDiff(
- historyItem.amountRefreshedRaw,
- historyItem.amountRefreshedEffective,
- )}
- />
- );
- }
-
- case "order-refused": {
- const { merchant, item } = parseSummary(
- historyItem.orderShortInfo.summary,
- );
- return (
- <HistoryItem
- icon={"X"}
- timestamp={historyItem.timestamp}
- small={i18n.str`Order Refused`}
- title={merchant}
- text={abbrev(item, 30)}
- />
- );
- }
-
- case "order-redirected": {
- const { merchant, item } = parseSummary(
- historyItem.newOrderShortInfo.summary,
- );
- return (
- <HistoryItem
- icon={"⟲"}
- small={i18n.str`Order redirected`}
- text={abbrev(item, 40)}
- timestamp={historyItem.timestamp}
- title={merchant}
- />
- );
- }
-
- case "payment-aborted": {
- const { merchant, item } = parseSummary(
- historyItem.orderShortInfo.summary,
- );
- return (
- <HistoryItem
- amount={historyItem.orderShortInfo.amount}
- fees={historyItem.amountLost}
- icon={"P"}
- small={i18n.str`Payment aborted`}
- text={abbrev(item, 40)}
- timestamp={historyItem.timestamp}
- title={merchant}
- />
- );
- }
-
- case "payment-sent": {
- const url = historyItem.orderShortInfo.fulfillmentUrl;
- const { merchant, item } = parseSummary(
- historyItem.orderShortInfo.summary,
- );
- const fees = amountDiff(
- historyItem.amountPaidWithFees,
- historyItem.orderShortInfo.amount,
- );
- const fulfillmentLinkElem = (
- <Fragment>
- <a href={url} onClick={openTab(url)}>
- {item ? abbrev(item, 30) : null}
- </a>
- </Fragment>
- );
- return (
- <HistoryItem
- amount={historyItem.orderShortInfo.amount}
- fees={fees}
- icon={"P"}
- negative={true}
- small={i18n.str`Payment Sent`}
- text={fulfillmentLinkElem}
- timestamp={historyItem.timestamp}
- title={merchant}
- />
- );
- }
- case "order-accepted": {
- const url = historyItem.orderShortInfo.fulfillmentUrl;
- const { merchant, item } = parseSummary(
- historyItem.orderShortInfo.summary,
- );
- const fulfillmentLinkElem = (
- <Fragment>
- <a href={url} onClick={openTab(url)}>
- {item ? abbrev(item, 40) : null}
- </a>
- </Fragment>
- );
- return (
- <HistoryItem
- negative={true}
- amount={historyItem.orderShortInfo.amount}
- icon={"P"}
- small={i18n.str`Order accepted`}
- text={fulfillmentLinkElem}
- timestamp={historyItem.timestamp}
- title={merchant}
- />
- );
- }
- case "reserve-balance-updated": {
- return (
- <HistoryItem
- timestamp={historyItem.timestamp}
- small={i18n.str`Reserve balance updated`}
- />
- );
- }
- case "refund": {
- const merchantElem = (
- <em>{abbrev(historyItem.orderShortInfo.summary, 25)}</em>
- );
- return (
- <HistoryItem
- icon={"R"}
- timestamp={historyItem.timestamp}
- small={i18n.str`Payment refund`}
- text={merchantElem}
- amount={historyItem.amountRefundedRaw}
- invalid={historyItem.amountRefundedInvalid}
- fees={amountDiff(
- amountDiff(
- historyItem.amountRefundedRaw,
- historyItem.amountRefundedInvalid,
- ),
- historyItem.amountRefundedEffective,
- )}
- />
- );
- }
- case "withdrawn": {
- const exchange = new URL(historyItem.exchangeBaseUrl).host;
- const fees = amountDiff(
- historyItem.amountWithdrawnRaw,
- historyItem.amountWithdrawnEffective,
- );
- return (
- <HistoryItem
- amount={historyItem.amountWithdrawnRaw}
- fees={fees}
- icon={"w"}
- small={i18n.str`Withdrawn`}
- title={exchange}
- timestamp={historyItem.timestamp}
- />
- );
- }
- case "tip-accepted": {
- return (
- <HistoryItem
- icon={"T"}
- negative={true}
- timestamp={historyItem.timestamp}
- title={<i18n.Translate wrap={Fragment}>Tip Accepted</i18n.Translate>}
- amount={historyItem.tipAmountRaw}
- />
- );
- }
- case "tip-declined": {
- return (
- <HistoryItem
- icon={"T"}
- timestamp={historyItem.timestamp}
- title={<i18n.Translate wrap={Fragment}>Tip Declined</i18n.Translate>}
- amount={historyItem.tipAmountRaw}
- />
- );
- }
- default:
- return (
- <HistoryItem
- timestamp={historyItem.timestamp}
- small={i18n.str`${formatAndCapitalize(historyItem.type)}`}
- />
- );
- }
-}
const HistoryComponent = (props: any): JSX.Element => {
- const record = props.record;
- return formatHistoryItem(record);
+ return <span>TBD</span>;
};
class WalletSettings extends React.Component<any, any> {
@@ -633,90 +330,6 @@ class WalletSettings extends React.Component<any, any> {
}
}
-class WalletHistory extends React.Component<any, any> {
- private myHistory: any[];
- private gotError = false;
- private unmounted = false;
- private hidenTypes: string[] = [
- "order-accepted",
- "order-redirected",
- "refreshed",
- "reserve-balance-updated",
- "exchange-updated",
- "exchange-added",
- ];
-
- componentWillMount(): void {
- this.update();
- this.setState({ filter: true });
- wxApi.onUpdateNotification(() => this.update());
- }
-
- componentWillUnmount(): void {
- console.log("history component unmounted");
- this.unmounted = true;
- }
-
- update(): void {
- chrome.runtime.sendMessage({ type: "get-history" }, (resp) => {
- if (this.unmounted) {
- return;
- }
- console.log("got history response");
- if (resp.error) {
- this.gotError = true;
- console.error("could not retrieve history", resp);
- this.setState({});
- return;
- }
- this.gotError = false;
- console.log("got history", resp.history);
- this.myHistory = resp.history;
- this.setState({});
- });
- }
-
- render(): JSX.Element {
- console.log("rendering history");
- const history: HistoryEvent[] = this.myHistory;
- if (this.gotError) {
- return <span>i18n.str`Error: could not retrieve event history`</span>;
- }
-
- if (!history) {
- // We're not ready yet
- return <span />;
- }
-
- const listing: any[] = [];
- const messages = history.reverse().filter((hEvent) => {
- if (!this.state.filter) return true;
- return this.hidenTypes.indexOf(hEvent.type) === -1;
- });
-
- for (const record of messages) {
- const item = <HistoryComponent key={record.eventId} record={record} />;
- listing.push(item);
- }
-
- if (listing.length > 0) {
- return (
- <div>
- <div className="container">{listing}</div>
- <div className="option">
- Filtered list{" "}
- <input
- type="checkbox"
- checked={this.state.filter}
- onChange={() => this.setState({ filter: !this.state.filter })}
- />
- </div>
- </div>
- );
- }
- return <p>{i18n.str`Your wallet has no events recorded.`}</p>;
- }
-}
function reload(): void {
try {
@@ -884,7 +497,6 @@ function WalletPopup(): JSX.Element {
<div style={{ margin: "1em" }}>
<Router>
<WalletBalanceView route="/balance" default />
- <WalletHistory route="/history" />
<WalletSettings route="/settings" />
<WalletDebug route="/debug" />
</Router>
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index d5a272160..793f4b5d3 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -117,10 +117,6 @@ async function handleMessage(
}
return needsWallet().updateExchangeFromUrl(detail.baseUrl);
}
- case "get-history": {
- // TODO: limit history length
- return needsWallet().getHistory();
- }
case "get-exchanges": {
return needsWallet().getExchangeRecords();
}