aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pages/auditors.html37
-rw-r--r--src/pages/auditors.tsx96
-rw-r--r--src/popup/popup.tsx4
-rw-r--r--src/types.ts12
-rw-r--r--src/wallet.ts28
-rw-r--r--src/wxApi.ts9
-rw-r--r--src/wxBackend.ts6
-rw-r--r--tsconfig.json1
8 files changed, 180 insertions, 13 deletions
diff --git a/src/pages/auditors.html b/src/pages/auditors.html
new file mode 100644
index 000000000..0a9740f03
--- /dev/null
+++ b/src/pages/auditors.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Taler Wallet: Auditors</title>
+
+ <link rel="stylesheet" type="text/css" href="../style/lang.css">
+ <link rel="stylesheet" type="text/css" href="../style/wallet.css">
+
+ <link rel="icon" href="/img/icon.png">
+
+ <script src="/src/vendor/URI.js"></script>
+ <script src="/src/vendor/react.js"></script>
+ <script src="/src/vendor/react-dom.js"></script>
+
+ <script src="/src/vendor/system-csp-production.src.js"></script>
+ <script src="/src/moduleTrampoline.js"></script>
+
+ <style>
+ .tree-item {
+ margin: 2em;
+ border-radius: 5px;
+ border: 1px solid gray;
+ padding: 1em;
+ }
+ .button-linky {
+ background: none;
+ color: black;
+ text-decoration: underline;
+ border: none;
+ }
+ </style>
+
+ <body>
+ <div id="container"></div>
+ </body>
+</html>
diff --git a/src/pages/auditors.tsx b/src/pages/auditors.tsx
new file mode 100644
index 000000000..b0bce8fd5
--- /dev/null
+++ b/src/pages/auditors.tsx
@@ -0,0 +1,96 @@
+/*
+ This file is part of TALER
+ (C) 2017 Inria
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * View and edit auditors.
+ *
+ * @author Florian Dold
+ */
+
+
+import { ExchangeRecord, DenominationRecord } from "src/types";
+import { AuditorRecord, CurrencyRecord, ReserveRecord, CoinRecord, PreCoinRecord, Denomination } from "src/types";
+import { ImplicitStateComponent, StateHolder } from "src/components";
+import {
+ getCurrencies,
+ updateCurrency,
+} from "src/wxApi";
+import { prettyAmount } from "src/renderHtml";
+import { getTalerStampDate } from "src/helpers";
+
+interface CurrencyListState {
+ currencies?: CurrencyRecord[];
+}
+
+class CurrencyList extends React.Component<any, CurrencyListState> {
+ constructor() {
+ super();
+ let port = chrome.runtime.connect();
+ port.onMessage.addListener((msg: any) => {
+ if (msg.notify) {
+ console.log("got notified");
+ this.update();
+ }
+ });
+ this.update();
+ this.state = {} as any;
+ }
+
+ async update() {
+ let currencies = await getCurrencies();
+ console.log("currencies: ", currencies);
+ this.setState({ currencies });
+ }
+
+ async confirmRemove(c: CurrencyRecord, a: AuditorRecord) {
+ if (window.confirm(`Do you really want to remove auditor ${a.baseUrl} for currency ${c.name}?`)) {
+ c.auditors = c.auditors.filter((x) => x.auditorPub != a.auditorPub);
+ await updateCurrency(c);
+ }
+ }
+
+ render(): JSX.Element {
+ let currencies = this.state.currencies;
+ if (!currencies) {
+ return <span>...</span>;
+ }
+ return (
+ <div>
+ {currencies.map(c => (
+ <div>
+ <h1>Currency {c.name}</h1>
+ <p>Displayed with {c.fractionalDigits} fractional digits.</p>
+ <p>Auditors:</p>
+ <ul>
+ {c.auditors.map(a => (
+ <li>{a.baseUrl} (<button className="button-linky" onClick={() => this.confirmRemove(c, a)}>Remove</button>)
+ <ul>
+ <li>valid until {new Date(a.expirationStamp).toString()}</li>
+ <li>public key {a.auditorPub}</li>
+ </ul>
+ </li>
+ ))}
+ </ul>
+ </div>
+ ))}
+ </div>
+ );
+ }
+}
+
+export function main() {
+ ReactDOM.render(<CurrencyList />, document.getElementById("container")!);
+}
diff --git a/src/popup/popup.tsx b/src/popup/popup.tsx
index dd87963c6..424c38110 100644
--- a/src/popup/popup.tsx
+++ b/src/popup/popup.tsx
@@ -325,8 +325,8 @@ class WalletBalanceView extends React.Component<any, any> {
);
});
if (listing.length > 0) {
- let link = chrome.extension.getURL("/src/pages/tree.html");
- let linkElem = <a href={link} target="_blank">advanced view</a>;
+ let link = chrome.extension.getURL("/src/pages/auditors.html");
+ let linkElem = <a href={link} target="_blank">auditors</a>;
return (
<div>
{listing}
diff --git a/src/types.ts b/src/types.ts
index 679c60502..6ac87639f 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -76,6 +76,18 @@ export interface ReserveRecord {
confirmed: boolean,
}
+export interface AuditorRecord {
+ baseUrl: string;
+ auditorPub: string;
+ expirationStamp: number;
+}
+
+export interface CurrencyRecord {
+ name: string;
+ fractionalDigits: number;
+ auditors: AuditorRecord[];
+}
+
@Checkable.Class
export class CreateReserveResponse {
diff --git a/src/wallet.ts b/src/wallet.ts
index a2d9e2ad9..506cde1f4 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -37,6 +37,8 @@ import {
RefreshSessionRecord,
ReserveCreationInfo,
ReserveRecord,
+ CurrencyRecord,
+ AuditorRecord,
WalletBalance,
WalletBalanceEntry,
WireInfo, DenominationRecord, DenominationStatus, denominationRecordFromKeys,
@@ -202,17 +204,6 @@ export interface NonceRecord {
pub: string;
}
-export interface AuditorRecord {
- baseUrl: string;
- auditorPub: string;
- expirationStamp: number;
-}
-
-export interface CurrencyRecord {
- name: string;
- fractionalDigits: number;
- auditors: AuditorRecord[];
-}
export interface ConfigRecord {
key: string;
@@ -1714,6 +1705,21 @@ export class Wallet {
.toArray();
}
+ async getCurrencies(): Promise<CurrencyRecord[]> {
+ return this.q()
+ .iter<CurrencyRecord>(Stores.currencies)
+ .flatMap((e) => [e])
+ .toArray();
+ }
+
+ async updateCurrency(currencyRecord: CurrencyRecord): Promise<void> {
+ console.log("updating currency to", currencyRecord);
+ await this.q()
+ .put(Stores.currencies, currencyRecord)
+ .finish();
+ this.notifier.notify();
+ }
+
async getReserves(exchangeBaseUrl: string): Promise<ReserveRecord[]> {
return this.q()
.iter<ReserveRecord>(Stores.reserves)
diff --git a/src/wxApi.ts b/src/wxApi.ts
index 15e27c2e7..327323648 100644
--- a/src/wxApi.ts
+++ b/src/wxApi.ts
@@ -20,6 +20,7 @@ import {
PreCoinRecord,
ReserveCreationInfo,
ExchangeRecord,
+ CurrencyRecord,
ReserveRecord, DenominationRecord
} from "./types";
@@ -58,6 +59,14 @@ export async function getExchanges(): Promise<ExchangeRecord[]> {
return await callBackend("get-exchanges");
}
+export async function getCurrencies(): Promise<CurrencyRecord[]> {
+ return await callBackend("get-currencies");
+}
+
+export async function updateCurrency(currencyRecord: CurrencyRecord): Promise<void> {
+ return await callBackend("update-currency", { currencyRecord });
+}
+
export async function getReserves(exchangeBaseUrl: string): Promise<ReserveRecord[]> {
return await callBackend("get-reserves", { exchangeBaseUrl });
}
diff --git a/src/wxBackend.ts b/src/wxBackend.ts
index ad738acfb..7c3143136 100644
--- a/src/wxBackend.ts
+++ b/src/wxBackend.ts
@@ -204,6 +204,12 @@ function makeHandlers(db: IDBDatabase,
["get-exchanges"]: function (detail, sender) {
return wallet.getExchanges();
},
+ ["get-currencies"]: function (detail, sender) {
+ return wallet.getCurrencies();
+ },
+ ["update-currency"]: function (detail, sender) {
+ return wallet.updateCurrency(detail.currencyRecord);
+ },
["get-reserves"]: function (detail, sender) {
if (typeof detail.exchangeBaseUrl !== "string") {
return Promise.reject(Error("exchangeBaseUrl missing"));
diff --git a/tsconfig.json b/tsconfig.json
index 417068de3..be850d2c1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -38,6 +38,7 @@
"src/i18n/strings.ts",
"src/logging.ts",
"src/moduleTrampoline.ts",
+ "src/pages/auditors.tsx",
"src/pages/confirm-contract.tsx",
"src/pages/confirm-create-reserve.tsx",
"src/pages/error.tsx",