gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-wallet-webex] branch master updated (2e9ecf95 -> 1c3


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] branch master updated (2e9ecf95 -> 1c3346cd)
Date: Mon, 29 May 2017 16:28:21 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a change to branch master
in repository wallet-webex.

    from 2e9ecf95 include sourcemaps even in production
     new d0e0c6ba fix linter errors
     new 1c3346cd less ad-hoc messaging, fix some lint warnings

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/crypto/cryptoApi.ts                    |   2 +-
 src/crypto/cryptoWorker.ts                 |   2 +-
 src/i18n.tsx                               |  56 +++++-----
 src/i18n/de.po                             |  36 +++---
 src/i18n/en-US.po                          |  36 +++---
 src/i18n/fr.po                             |  36 +++---
 src/i18n/it.po                             |  36 +++---
 src/i18n/taler-wallet-webex.pot            |  36 +++---
 src/types.ts                               |  52 +++++++++
 src/wallet.ts                              |  73 +++---------
 src/webex/pages/confirm-contract.tsx       | 117 ++++++++-----------
 src/webex/pages/confirm-create-reserve.tsx | 160 +++++++++++++-------------
 src/webex/pages/error.tsx                  |   4 +-
 src/webex/pages/logs.tsx                   |  13 ++-
 src/webex/pages/payback.tsx                |  33 +++---
 src/webex/pages/popup.tsx                  | 173 +++++++++++++++--------------
 src/webex/pages/tree.tsx                   |  70 ++++++------
 src/webex/renderHtml.tsx                   |  10 +-
 src/webex/wxApi.ts                         |  26 +++++
 src/webex/wxBackend.ts                     |   2 +-
 webpack.config.js                          |   3 +
 21 files changed, 500 insertions(+), 476 deletions(-)

diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts
index 3c5eb84d..b5d7d4fb 100644
--- a/src/crypto/cryptoApi.ts
+++ b/src/crypto/cryptoApi.ts
@@ -27,6 +27,7 @@ import {
   AmountJson,
   CoinRecord,
   DenominationRecord,
+  OfferRecord,
   PayCoinInfo,
   PaybackRequest,
   PreCoinRecord,
@@ -37,7 +38,6 @@ import {
 
 import {
   CoinWithDenom,
-  OfferRecord,
 } from "../wallet";
 
 import * as timer from "../timer";
diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts
index 1a337446..85a0425b 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -29,6 +29,7 @@ import {
   CoinRecord,
   CoinStatus,
   DenominationRecord,
+  OfferRecord,
   PayCoinInfo,
   PaybackRequest,
   PreCoinRecord,
@@ -39,7 +40,6 @@ import {
 } from "../types";
 import {
   CoinWithDenom,
-  OfferRecord,
 } from "../wallet";
 
 import {
diff --git a/src/i18n.tsx b/src/i18n.tsx
index 48631afb..8c3d5419 100644
--- a/src/i18n.tsx
+++ b/src/i18n.tsx
@@ -40,7 +40,7 @@ if (!strings[lang]) {
   console.log(`language ${lang} not found, defaulting to english`);
 }
 
-let jed = new jedLib.Jed(strings[lang]);
+const jed = new jedLib.Jed(strings[lang]);
 
 
 /**
@@ -51,7 +51,7 @@ function toI18nString(strings: ReadonlyArray<string>) {
   for (let i = 0; i < strings.length; i++) {
     str += strings[i];
     if (i < strings.length - 1) {
-      str += "%"+ (i+1) +"$s";
+      str += `%${i + 1}$s`;
     }
   }
   return str;
@@ -62,8 +62,8 @@ function toI18nString(strings: ReadonlyArray<string>) {
  * Internationalize a string template with arbitrary serialized values.
  */
 export function str(strings: TemplateStringsArray, ...values: any[]) {
-  let str = toI18nString(strings);
-  let tr = jed.translate(str).ifPlural(1, str).fetch(...values);
+  const str = toI18nString(strings);
+  const tr = jed.translate(str).ifPlural(1, str).fetch(...values);
   return tr;
 }
 
@@ -75,7 +75,7 @@ interface TranslateSwitchProps {
 
 function stringifyChildren(children: any): string {
   let n = 1;
-  let ss = React.Children.map(children, (c) => {
+  const ss = React.Children.map(children, (c) => {
     if (typeof c === "string") {
       return c;
     }
@@ -113,23 +113,23 @@ interface TranslateProps {
  */
 export class Translate extends React.Component<TranslateProps,void> {
   render(): JSX.Element {
-    let s = stringifyChildren(this.props.children);
-    let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
-    let childArray = React.Children.toArray(this.props.children!);
+    const s = stringifyChildren(this.props.children);
+    const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
+    const childArray = React.Children.toArray(this.props.children!);
     for (let i = 0; i < childArray.length - 1; ++i) {
       if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == 
"string") {
         childArray[i+1] = (childArray[i] as string).concat(childArray[i+1] as 
string);
         childArray.splice(i,1);
       }
     }
-    let result = [];
+    const result = [];
     while (childArray.length > 0) {
-      let x = childArray.shift();
+      const x = childArray.shift();
       if (x === undefined) {
         continue;
       }
       if (typeof x === "string") {
-        let t = tr.shift();
+        const t = tr.shift();
         result.push(t);
       } else {
         result.push(x);
@@ -159,7 +159,7 @@ export class TranslateSwitch extends 
React.Component<TranslateSwitchProps,void>{
   render(): JSX.Element {
     let singular: React.ReactElement<TranslationPluralProps> | undefined;
     let plural: React.ReactElement<TranslationPluralProps> | undefined;
-    let children = this.props.children;
+    const children = this.props.children;
     if (children) {
       React.Children.forEach(children, (child: any) => {
         if (child.type == TranslatePlural) {
@@ -192,23 +192,23 @@ interface TranslationPluralProps {
  */
 export class TranslatePlural extends 
React.Component<TranslationPluralProps,void> {
   render(): JSX.Element {
-    let s = stringifyChildren(this.props.children);
-    let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
-    let childArray = React.Children.toArray(this.props.children!);
+    const s = stringifyChildren(this.props.children);
+    const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
+    const childArray = React.Children.toArray(this.props.children!);
     for (let i = 0; i < childArray.length - 1; ++i) {
-      if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == 
"string") {
-        childArray[i+i] = childArray[i] as string + childArray[i+1] as string;
+      if ((typeof childArray[i]) == "string" && (typeof childArray[i + 1]) == 
"string") {
+        childArray[i+i] = childArray[i] as string + childArray[i + 1] as 
string;
         childArray.splice(i,1);
       }
     }
-    let result = [];
+    const result = [];
     while (childArray.length > 0) {
-      let x = childArray.shift();
+      const x = childArray.shift();
       if (x === undefined) {
         continue;
       }
       if (typeof x === "string") {
-        let t = tr.shift();
+        const t = tr.shift();
         result.push(t);
       } else {
         result.push(x);
@@ -224,23 +224,23 @@ export class TranslatePlural extends 
React.Component<TranslationPluralProps,void
  */
 export class TranslateSingular extends 
React.Component<TranslationPluralProps,void> {
   render(): JSX.Element {
-    let s = stringifyChildren(this.props.children);
-    let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
-    let childArray = React.Children.toArray(this.props.children!);
+    const s = stringifyChildren(this.props.children);
+    const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: 
number) => i % 2 == 0);
+    const childArray = React.Children.toArray(this.props.children!);
     for (let i = 0; i < childArray.length - 1; ++i) {
-      if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == 
"string") {
-        childArray[i+i] = childArray[i] as string + childArray[i+1] as string;
+      if ((typeof childArray[i]) == "string" && (typeof childArray[i + 1]) == 
"string") {
+        childArray[i+i] = childArray[i] as string + childArray[i + 1] as 
string;
         childArray.splice(i,1);
       }
     }
-    let result = [];
+    const result = [];
     while (childArray.length > 0) {
-      let x = childArray.shift();
+      const x = childArray.shift();
       if (x === undefined) {
         continue;
       }
       if (typeof x === "string") {
-        let t = tr.shift();
+        const t = tr.shift();
         result.push(t);
       } else {
         result.push(x);
diff --git a/src/i18n/de.po b/src/i18n/de.po
index 39daf9b2..a76705b9 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -197,91 +197,91 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:160
+#: src/webex/pages/popup.tsx:163
 #, c-format
 msgid "Balance"
 msgstr "Saldo"
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:166
 #, c-format
 msgid "History"
 msgstr "Verlauf"
 
-#: src/webex/pages/popup.tsx:166
+#: src/webex/pages/popup.tsx:169
 #, c-format
 msgid "Debug"
 msgstr "Debug"
 
-#: src/webex/pages/popup.tsx:238
+#: src/webex/pages/popup.tsx:241
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:243
+#: src/webex/pages/popup.tsx:246
 #, fuzzy, c-format
 msgid ""
 "You have no balance to show. Need some\n"
 " %1$s getting started?\n"
 msgstr "Sie haben kein Digitalgeld. Wollen Sie %1$s? abheben?"
 
-#: src/webex/pages/popup.tsx:260
+#: src/webex/pages/popup.tsx:263
 #, c-format
 msgid "%1$s incoming\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:273
+#: src/webex/pages/popup.tsx:276
 #, c-format
 msgid "%1$s being spent\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:299
+#: src/webex/pages/popup.tsx:302
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:340
+#: src/webex/pages/popup.tsx:343
 #, fuzzy, c-format
 msgid "Bank requested reserve (%1$s) for%2$s.\n"
 msgstr "Bank bestätig anlegen der Reserve (%1$s) bei %2$s"
 
-#: src/webex/pages/popup.tsx:349
+#: src/webex/pages/popup.tsx:352
 #, fuzzy, c-format
 msgid ""
 "Started to withdraw\n"
 " %1$s from%2$s(%3$s).\n"
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Merchant%1$soffered contract%2$s;\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:371
+#: src/webex/pages/popup.tsx:374
 #, fuzzy, c-format
 msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, fuzzy, c-format
 msgid "Paid%1$sto merchant%2$s.  (%3$s)\n"
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:388
+#: src/webex/pages/popup.tsx:391
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:431
+#: src/webex/pages/popup.tsx:434
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:465
+#: src/webex/pages/popup.tsx:468
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
 
-#: src/webex/renderHtml.tsx:49
+#: src/webex/renderHtml.tsx:51
 #, fuzzy, c-format
 msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
 msgstr ""
@@ -289,7 +289,7 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/renderHtml.tsx:54
+#: src/webex/renderHtml.tsx:56
 #, fuzzy, c-format
 msgid "You are about to purchase:"
 msgstr "Sie sind dabei, Folgendes zu kaufen:"
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index 502bfae3..86ca8ccc 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -197,96 +197,96 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:160
+#: src/webex/pages/popup.tsx:163
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:166
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:166
+#: src/webex/pages/popup.tsx:169
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:238
+#: src/webex/pages/popup.tsx:241
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:243
+#: src/webex/pages/popup.tsx:246
 #, c-format
 msgid ""
 "You have no balance to show. Need some\n"
 " %1$s getting started?\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:260
+#: src/webex/pages/popup.tsx:263
 #, c-format
 msgid "%1$s incoming\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:273
+#: src/webex/pages/popup.tsx:276
 #, c-format
 msgid "%1$s being spent\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:299
+#: src/webex/pages/popup.tsx:302
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:340
+#: src/webex/pages/popup.tsx:343
 #, c-format
 msgid "Bank requested reserve (%1$s) for%2$s.\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:349
+#: src/webex/pages/popup.tsx:352
 #, c-format
 msgid ""
 "Started to withdraw\n"
 " %1$s from%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Merchant%1$soffered contract%2$s;\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:371
+#: src/webex/pages/popup.tsx:374
 #, c-format
 msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Paid%1$sto merchant%2$s.  (%3$s)\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:388
+#: src/webex/pages/popup.tsx:391
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:431
+#: src/webex/pages/popup.tsx:434
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:465
+#: src/webex/pages/popup.tsx:468
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
 
-#: src/webex/renderHtml.tsx:49
+#: src/webex/renderHtml.tsx:51
 #, c-format
 msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
 msgstr ""
 
-#: src/webex/renderHtml.tsx:54
+#: src/webex/renderHtml.tsx:56
 #, c-format
 msgid "You are about to purchase:"
 msgstr ""
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index cdf657b1..71e273b2 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -197,96 +197,96 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:160
+#: src/webex/pages/popup.tsx:163
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:166
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:166
+#: src/webex/pages/popup.tsx:169
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:238
+#: src/webex/pages/popup.tsx:241
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:243
+#: src/webex/pages/popup.tsx:246
 #, c-format
 msgid ""
 "You have no balance to show. Need some\n"
 " %1$s getting started?\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:260
+#: src/webex/pages/popup.tsx:263
 #, c-format
 msgid "%1$s incoming\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:273
+#: src/webex/pages/popup.tsx:276
 #, c-format
 msgid "%1$s being spent\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:299
+#: src/webex/pages/popup.tsx:302
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:340
+#: src/webex/pages/popup.tsx:343
 #, c-format
 msgid "Bank requested reserve (%1$s) for%2$s.\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:349
+#: src/webex/pages/popup.tsx:352
 #, c-format
 msgid ""
 "Started to withdraw\n"
 " %1$s from%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Merchant%1$soffered contract%2$s;\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:371
+#: src/webex/pages/popup.tsx:374
 #, c-format
 msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Paid%1$sto merchant%2$s.  (%3$s)\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:388
+#: src/webex/pages/popup.tsx:391
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:431
+#: src/webex/pages/popup.tsx:434
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:465
+#: src/webex/pages/popup.tsx:468
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
 
-#: src/webex/renderHtml.tsx:49
+#: src/webex/renderHtml.tsx:51
 #, c-format
 msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
 msgstr ""
 
-#: src/webex/renderHtml.tsx:54
+#: src/webex/renderHtml.tsx:56
 #, c-format
 msgid "You are about to purchase:"
 msgstr ""
diff --git a/src/i18n/it.po b/src/i18n/it.po
index cdf657b1..71e273b2 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -197,96 +197,96 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:160
+#: src/webex/pages/popup.tsx:163
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:166
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:166
+#: src/webex/pages/popup.tsx:169
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:238
+#: src/webex/pages/popup.tsx:241
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:243
+#: src/webex/pages/popup.tsx:246
 #, c-format
 msgid ""
 "You have no balance to show. Need some\n"
 " %1$s getting started?\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:260
+#: src/webex/pages/popup.tsx:263
 #, c-format
 msgid "%1$s incoming\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:273
+#: src/webex/pages/popup.tsx:276
 #, c-format
 msgid "%1$s being spent\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:299
+#: src/webex/pages/popup.tsx:302
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:340
+#: src/webex/pages/popup.tsx:343
 #, c-format
 msgid "Bank requested reserve (%1$s) for%2$s.\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:349
+#: src/webex/pages/popup.tsx:352
 #, c-format
 msgid ""
 "Started to withdraw\n"
 " %1$s from%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Merchant%1$soffered contract%2$s;\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:371
+#: src/webex/pages/popup.tsx:374
 #, c-format
 msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Paid%1$sto merchant%2$s.  (%3$s)\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:388
+#: src/webex/pages/popup.tsx:391
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:431
+#: src/webex/pages/popup.tsx:434
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:465
+#: src/webex/pages/popup.tsx:468
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
 
-#: src/webex/renderHtml.tsx:49
+#: src/webex/renderHtml.tsx:51
 #, c-format
 msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
 msgstr ""
 
-#: src/webex/renderHtml.tsx:54
+#: src/webex/renderHtml.tsx:56
 #, c-format
 msgid "You are about to purchase:"
 msgstr ""
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index cdf657b1..71e273b2 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -197,96 +197,96 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:160
+#: src/webex/pages/popup.tsx:163
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:166
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:166
+#: src/webex/pages/popup.tsx:169
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:238
+#: src/webex/pages/popup.tsx:241
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:243
+#: src/webex/pages/popup.tsx:246
 #, c-format
 msgid ""
 "You have no balance to show. Need some\n"
 " %1$s getting started?\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:260
+#: src/webex/pages/popup.tsx:263
 #, c-format
 msgid "%1$s incoming\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:273
+#: src/webex/pages/popup.tsx:276
 #, c-format
 msgid "%1$s being spent\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:299
+#: src/webex/pages/popup.tsx:302
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:340
+#: src/webex/pages/popup.tsx:343
 #, c-format
 msgid "Bank requested reserve (%1$s) for%2$s.\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:349
+#: src/webex/pages/popup.tsx:352
 #, c-format
 msgid ""
 "Started to withdraw\n"
 " %1$s from%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Merchant%1$soffered contract%2$s;\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:371
+#: src/webex/pages/popup.tsx:374
 #, c-format
 msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Paid%1$sto merchant%2$s.  (%3$s)\n"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:388
+#: src/webex/pages/popup.tsx:391
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:431
+#: src/webex/pages/popup.tsx:434
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:465
+#: src/webex/pages/popup.tsx:468
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
 
-#: src/webex/renderHtml.tsx:49
+#: src/webex/renderHtml.tsx:51
 #, c-format
 msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
 msgstr ""
 
-#: src/webex/renderHtml.tsx:54
+#: src/webex/renderHtml.tsx:56
 #, c-format
 msgid "You are about to purchase:"
 msgstr ""
diff --git a/src/types.ts b/src/types.ts
index 0371aab7..8b5f4063 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1075,6 +1075,51 @@ export class Contract {
 
 
 /**
+ * Offer record, stored in the wallet's database.
+ */
address@hidden()
+export class OfferRecord {
+  /**
+   * The contract that was offered by the merchant.
+   */
+  @Checkable.Value(Contract)
+  contract: Contract;
+
+  /**
+   * Signature by the merchant over the contract details.
+   */
+  @Checkable.String
+  merchant_sig: string;
+
+  /**
+   * Hash of the contract terms.
+   */
+  @Checkable.String
+  H_contract: string;
+
+  /**
+   * Time when the offer was made.
+   */
+  @Checkable.Number
+  offer_time: number;
+
+  /**
+   * Serial ID when the offer is stored in the wallet DB.
+   */
+  @Checkable.Optional(Checkable.Number)
+  id?: number;
+
+  /**
+   * Verify that a value matches the schema of this class and convert it into a
+   * member.
+   */
+  static checked: (obj: any) => OfferRecord;
+}
+
+
+
+
+/**
  * Wire fee for one wire method as stored in the
  * wallet's database.
  */
@@ -1333,3 +1378,10 @@ export interface Notifier {
 export function mkAmount(value: number, fraction: number, currency: string): 
AmountJson {
   return {value, fraction, currency};
 }
+
+/**
+ * Possible responses for checkPay.
+ */
+export type CheckPayResult = "paid" | "payment-possible" | 
"insufficient-balance";
+
+export type ConfirmPayResult = "paid" | "insufficient-balance";
diff --git a/src/wallet.ts b/src/wallet.ts
index 743042b9..5564162b 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -50,9 +50,11 @@ import {
   Amounts,
   Auditor,
   AuditorRecord,
+  CheckPayResult,
   CoinPaySig,
   CoinRecord,
   CoinStatus,
+  ConfirmPayResult,
   Contract,
   CreateReserveResponse,
   CurrencyRecord,
@@ -63,6 +65,7 @@ import {
   ExchangeRecord,
   ExchangeWireFeesRecord,
   Notifier,
+  OfferRecord,
   PayCoinInfo,
   PaybackConfirmation,
   PreCoinRecord,
@@ -272,48 +275,6 @@ export class ConfirmReserveRequest {
 
 
 /**
- * Offer record, stored in the wallet's database.
- */
address@hidden()
-export class OfferRecord {
-  /**
-   * The contract that was offered by the merchant.
-   */
-  @Checkable.Value(Contract)
-  contract: Contract;
-
-  /**
-   * Signature by the merchant over the contract details.
-   */
-  @Checkable.String
-  merchant_sig: string;
-
-  /**
-   * Hash of the contract terms.
-   */
-  @Checkable.String
-  H_contract: string;
-
-  /**
-   * Time when the offer was made.
-   */
-  @Checkable.Number
-  offer_time: number;
-
-  /**
-   * Serial ID when the offer is stored in the wallet DB.
-   */
-  @Checkable.Optional(Checkable.Number)
-  id?: number;
-
-  /**
-   * Verify that a value matches the schema of this class and convert it into a
-   * member.
-   */
-  static checked: (obj: any) => OfferRecord;
-}
-
-/**
  * Activity history record.
  */
 export interface HistoryRecord {
@@ -981,14 +942,14 @@ export class Wallet {
    * Add a contract to the wallet and sign coins,
    * but do not send them yet.
    */
-  async confirmPay(offer: OfferRecord): Promise<any> {
+  async confirmPay(offer: OfferRecord): Promise<ConfirmPayResult> {
     console.log("executing confirmPay");
 
     const transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
 
     if (transaction) {
       // Already payed ...
-      return {};
+      return "paid";
     }
 
     const res = await this.getCoinsForPayment({
@@ -1007,29 +968,25 @@ export class Wallet {
 
     if (!res) {
       console.log("not confirming payment, insufficient coins");
-      return {
-        error: "coins-insufficient",
-      };
+      return "insufficient-balance";
     }
     const {exchangeUrl, cds} = res;
 
     const ds = await this.cryptoApi.signDeposit(offer, cds);
-    await this.recordConfirmPay(offer,
-                                ds,
-                                exchangeUrl);
-    return {};
+    await this.recordConfirmPay(offer, ds, exchangeUrl);
+    return "paid";
   }
 
 
   /**
-   * Add a contract to the wallet and sign coins,
-   * but do not send them yet.
+   * Check if payment for an offer is possible, or if the offer has already
+   * been payed for.
    */
-  async checkPay(offer: OfferRecord): Promise<any> {
+  async checkPay(offer: OfferRecord): Promise<CheckPayResult> {
     // First check if we already payed for it.
     const transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
     if (transaction) {
-      return {isPayed: true};
+      return "insufficient-balance";
     }
 
     // If not already payed, check if we could pay for it.
@@ -1046,11 +1003,9 @@ export class Wallet {
 
     if (!res) {
       console.log("not confirming payment, insufficient coins");
-      return {
-        error: "coins-insufficient",
-      };
+      return "insufficient-balance";
     }
-    return {isPayed: false};
+    return "payment-possible";
   }
 
 
diff --git a/src/webex/pages/confirm-contract.tsx 
b/src/webex/pages/confirm-contract.tsx
index 011df27a..cc302584 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -24,11 +24,15 @@
  * Imports.
  */
 import * as i18n from "../../i18n";
-import { Contract, AmountJson, ExchangeRecord } from "../../types";
-import { OfferRecord } from "../../wallet";
+import {
+  AmountJson,
+  Contract,
+  ExchangeRecord,
+  OfferRecord,
+} from "../../types";
 
 import { renderContract } from "../renderHtml";
-import { getExchanges } from "../wxApi";
+import * as wxApi from "../wxApi";
 
 import * as React from "react";
 import * as ReactDOM from "react-dom";
@@ -125,85 +129,56 @@ class ContractPrompt extends 
React.Component<ContractPromptProps, ContractPrompt
   }
 
   async update() {
-    let offer = await this.getOffer();
+    let offer = await wxApi.getOffer(this.props.offerId);
     this.setState({offer} as any);
     this.checkPayment();
-    let exchanges = await getExchanges();
+    let exchanges = await wxApi.getExchanges();
     this.setState({exchanges} as any);
   }
 
-  getOffer(): Promise<OfferRecord> {
-    return new Promise<OfferRecord>((resolve, reject) => {
-      let msg = {
-        type: 'get-offer',
-        detail: {
-          offerId: this.props.offerId
-        }
-      };
-      chrome.runtime.sendMessage(msg, (resp) => {
-        resolve(resp);
-      });
-    })
-  }
-
-  checkPayment() {
-    let msg = {
-      type: 'check-pay',
-      detail: {
-        offer: this.state.offer
-      }
-    };
-    chrome.runtime.sendMessage(msg, (resp) => {
-      if (resp.error) {
-        console.log("check-pay error", JSON.stringify(resp));
-        switch (resp.error) {
-          case "coins-insufficient":
-            let msgInsufficient = i18n.str`You have insufficient funds of the 
requested currency in your wallet.`;
-            let msgNoMatch = i18n.str`You do not have any funds from an 
exchange that is accepted by this merchant. None of the exchanges accepted by 
the merchant is known to your wallet.`;
-            if (this.state.exchanges && this.state.offer) {
-              let acceptedExchangePubs = 
this.state.offer.contract.exchanges.map((e) => e.master_pub);
-              let ex = this.state.exchanges.find((e) => 
acceptedExchangePubs.indexOf(e.masterPublicKey) >= 0);
-              if (ex) {
-                this.setState({error: msgInsufficient});
-              } else {
-                this.setState({error: msgNoMatch});
-              }
-            } else {
-              this.setState({error: msgInsufficient});
-            }
-            break;
-          default:
-            this.setState({error: `Error: ${resp.error}`});
-            break;
+  async checkPayment() {
+    let offer = this.state.offer;
+    if (!offer) {
+      return;
+    }
+    const payStatus = await wxApi.checkPay(offer);
+
+    if (payStatus === "insufficient-balance") {
+      let msgInsufficient = i18n.str`You have insufficient funds of the 
requested currency in your wallet.`;
+      let msgNoMatch = i18n.str`You do not have any funds from an exchange 
that is accepted by this merchant. None of the exchanges accepted by the 
merchant is known to your wallet.`;
+      if (this.state.exchanges && this.state.offer) {
+        let acceptedExchangePubs = this.state.offer.contract.exchanges.map((e) 
=> e.master_pub);
+        let ex = this.state.exchanges.find((e) => 
acceptedExchangePubs.indexOf(e.masterPublicKey) >= 0);
+        if (ex) {
+          this.setState({error: msgInsufficient});
+        } else {
+          this.setState({error: msgNoMatch});
         }
-        this.setState({payDisabled: true});
       } else {
-        this.setState({payDisabled: false, error: null});
+        this.setState({error: msgInsufficient});
       }
-      this.setState({} as any);
-      window.setTimeout(() => this.checkPayment(), 500);
-    });
+      this.setState({payDisabled: true});
+    } else {
+      this.setState({payDisabled: false, error: null});
+    }
+    window.setTimeout(() => this.checkPayment(), 500);
   }
 
-  doPayment() {
-    let d = {offer: this.state.offer};
-    chrome.runtime.sendMessage({type: 'confirm-pay', detail: d}, (resp) => {
-      if (resp.error) {
-        console.log("confirm-pay error", JSON.stringify(resp));
-        switch (resp.error) {
-          case "coins-insufficient":
-            this.setState({error: "You do not have enough coins of the 
requested currency."});
-            break;
-          default:
-            this.setState({error: `Error: ${resp.error}`});
-            break;
-        }
+  async doPayment() {
+    let offer = this.state.offer;
+    if (!offer) {
+      return;
+    }
+    const payStatus = await wxApi.confirmPay(offer);
+    switch (payStatus) {
+      case "insufficient-balance":
+        this.checkPayment();
         return;
-      }
-      let c = d.offer!.contract;
-      console.log("contract", c);
-      document.location.href = c.fulfillment_url;
-    });
+      case "paid":
+        console.log("contract", offer.contract);
+        document.location.href = offer.contract.fulfillment_url;
+        break;
+    }
   }
 
 
diff --git a/src/webex/pages/confirm-create-reserve.tsx 
b/src/webex/pages/confirm-create-reserve.tsx
index 6ece92e2..50a1045e 100644
--- a/src/webex/pages/confirm-create-reserve.tsx
+++ b/src/webex/pages/confirm-create-reserve.tsx
@@ -23,15 +23,23 @@
  */
 
 import {amountToPretty, canonicalizeBaseUrl} from "../../helpers";
+import * as i18n from "../../i18n";
 import {
-  AmountJson, CreateReserveResponse,
-  ReserveCreationInfo, Amounts,
-  Denomination, DenominationRecord, CurrencyRecord
+  AmountJson,
+  Amounts,
+  CreateReserveResponse,
+  CurrencyRecord,
+  Denomination,
+  DenominationRecord,
+  ReserveCreationInfo,
 } from "../../types";
-import * as i18n from "../../i18n";
 
-import {getReserveCreationInfo, getCurrency, getExchangeInfo} from "../wxApi";
 import {ImplicitStateComponent, StateHolder} from "../components";
+import {
+  getCurrency,
+  getExchangeInfo,
+  getReserveCreationInfo,
+} from "../wxApi";
 
 import * as React from "react";
 import * as ReactDOM from "react-dom";
@@ -46,8 +54,8 @@ function delay<T>(delayMs: number, value: T): Promise<T> {
 }
 
 class EventTrigger {
-  triggerResolve: any;
-  triggerPromise: Promise<boolean>;
+  private triggerResolve: any;
+  private triggerPromise: Promise<boolean>;
 
   constructor() {
     this.reset();
@@ -86,11 +94,11 @@ class Collapsible extends React.Component<CollapsibleProps, 
CollapsibleState> {
   }
   render() {
     const doOpen = (e: any) => {
-      this.setState({collapsed: false})
-      e.preventDefault()
+      this.setState({collapsed: false});
+      e.preventDefault();
     };
     const doClose = (e: any) => {
-      this.setState({collapsed: true})
+      this.setState({collapsed: true});
       e.preventDefault();
     };
     if (this.state.collapsed) {
@@ -113,7 +121,7 @@ function renderAuditorDetails(rci: 
ReserveCreationInfo|null) {
       </p>
     );
   }
-  if (rci.exchangeInfo.auditors.length == 0) {
+  if (rci.exchangeInfo.auditors.length === 0) {
     return (
       <p>
         The exchange is not audited by any auditors.
@@ -122,7 +130,7 @@ function renderAuditorDetails(rci: 
ReserveCreationInfo|null) {
   }
   return (
     <div>
-      {rci.exchangeInfo.auditors.map(a => (
+      {rci.exchangeInfo.auditors.map((a) => (
         <h3>Auditor {a.url}</h3>
       ))}
     </div>
@@ -138,14 +146,14 @@ function renderReserveCreationDetails(rci: 
ReserveCreationInfo|null) {
     );
   }
 
-  let denoms = rci.selectedDenoms;
+  const denoms = rci.selectedDenoms;
 
-  let countByPub: {[s: string]: number} = {};
-  let uniq: DenominationRecord[] = [];
+  const countByPub: {[s: string]: number} = {};
+  const uniq: DenominationRecord[] = [];
 
   denoms.forEach((x: DenominationRecord) => {
     let c = countByPub[x.denomPub] || 0;
-    if (c == 0) {
+    if (c === 0) {
       uniq.push(x);
     }
     c += 1;
@@ -177,19 +185,19 @@ function renderReserveCreationDetails(rci: 
ReserveCreationInfo|null) {
         </tr>
       </thead>,
       <tbody>
-      {rci!.wireFees.feesForType[s].map(f => (
+      {rci!.wireFees.feesForType[s].map((f) => (
         <tr>
           <td>{moment.unix(f.endStamp).format("llll")}</td>
           <td>{amountToPretty(f.wireFee)}</td>
           <td>{amountToPretty(f.closingFee)}</td>
         </tr>
       ))}
-      </tbody>
+      </tbody>,
     ];
   }
 
-  let withdrawFeeStr = amountToPretty(rci.withdrawFee);
-  let overheadStr = amountToPretty(rci.overhead);
+  const withdrawFeeStr = amountToPretty(rci.withdrawFee);
+  const overheadStr = amountToPretty(rci.overhead);
 
   return (
     <div>
@@ -221,28 +229,10 @@ function renderReserveCreationDetails(rci: 
ReserveCreationInfo|null) {
 }
 
 
-function getSuggestedExchange(currency: string): Promise<string> {
-  // TODO: make this request go to the wallet backend
-  // Right now, this is a stub.
-  const defaultExchange: {[s: string]: string} = {
-    "KUDOS": "https://exchange.demo.taler.net";,
-    "PUDOS": "https://exchange.test.taler.net";,
-  };
-
-  let exchange = defaultExchange[currency];
-
-  if (!exchange) {
-    exchange = ""
-  }
-
-  return Promise.resolve(exchange);
-}
-
-
 function WithdrawFee(props: {reserveCreationInfo: ReserveCreationInfo|null}): 
JSX.Element {
   if (props.reserveCreationInfo) {
-    let {overhead, withdrawFee} = props.reserveCreationInfo;
-    let totalCost = Amounts.add(overhead, withdrawFee).amount;
+    const {overhead, withdrawFee} = props.reserveCreationInfo;
+    const totalCost = Amounts.add(overhead, withdrawFee).amount;
     return <p>{i18n.str`Withdraw fees:`} {amountToPretty(totalCost)}</p>;
   }
   return <p />;
@@ -263,10 +253,10 @@ interface ManualSelectionProps {
 }
 
 class ManualSelection extends ImplicitStateComponent<ManualSelectionProps> {
-  url: StateHolder<string> = this.makeState("");
-  errorMessage: StateHolder<string|null> = this.makeState(null);
-  isOkay: StateHolder<boolean> = this.makeState(false);
-  updateEvent = new EventTrigger();
+  private url: StateHolder<string> = this.makeState("");
+  private errorMessage: StateHolder<string|null> = this.makeState(null);
+  private isOkay: StateHolder<boolean> = this.makeState(false);
+  private updateEvent = new EventTrigger();
   constructor(p: ManualSelectionProps) {
     super(p);
     this.url(p.initialUrl);
@@ -300,23 +290,23 @@ class ManualSelection extends 
ImplicitStateComponent<ManualSelectionProps> {
     if (!this.url()) {
       return;
     }
-    let parsedUrl = new URI(this.url()!);
+    const parsedUrl = new URI(this.url()!);
     if (parsedUrl.is("relative")) {
       this.errorMessage(i18n.str`Error: URL may not be relative`);
       this.isOkay(false);
       return;
     }
     try {
-      let url = canonicalizeBaseUrl(this.url()!);
-      let r = await getExchangeInfo(url)
-      console.log("getExchangeInfo returned")
+      const url = canonicalizeBaseUrl(this.url()!);
+      const r = await getExchangeInfo(url);
+      console.log("getExchangeInfo returned");
       this.isOkay(true);
     } catch (e) {
       console.log("got error", e);
       if (e.hasOwnProperty("httpStatus")) {
         this.errorMessage(`Error: request failed with status ${e.httpStatus}`);
       } else if (e.hasOwnProperty("errorResponse")) {
-        let resp = e.errorResponse;
+        const resp = e.errorResponse;
         this.errorMessage(`Error: ${resp.error} (${resp.hint})`);
       } else {
         this.errorMessage("invalid exchange URL");
@@ -329,7 +319,7 @@ class ManualSelection extends 
ImplicitStateComponent<ManualSelectionProps> {
     this.errorMessage(null);
     this.isOkay(false);
     this.updateEvent.trigger();
-    let waited = await this.updateEvent.wait(200);
+    const waited = await this.updateEvent.wait(200);
     if (waited) {
       // Run the actual update if nobody else preempted us.
       this.update();
@@ -339,24 +329,24 @@ class ManualSelection extends 
ImplicitStateComponent<ManualSelectionProps> {
 
 
 class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> 
{
-  statusString: StateHolder<string|null> = this.makeState(null);
-  reserveCreationInfo: StateHolder<ReserveCreationInfo|null> = this.makeState(
+  private statusString: StateHolder<string|null> = this.makeState(null);
+  private reserveCreationInfo: StateHolder<ReserveCreationInfo|null> = 
this.makeState(
     null);
-  url: StateHolder<string|null> = this.makeState(null);
+  private url: StateHolder<string|null> = this.makeState(null);
 
-  selectingExchange: StateHolder<boolean> = this.makeState(false);
+  private selectingExchange: StateHolder<boolean> = this.makeState(false);
 
   constructor(props: ExchangeSelectionProps) {
     super(props);
-    let prefilledExchangesUrls = [];
+    const prefilledExchangesUrls = [];
     if (props.currencyRecord) {
-      let exchanges = props.currencyRecord.exchanges.map((x) => x.baseUrl);
+      const exchanges = props.currencyRecord.exchanges.map((x) => x.baseUrl);
       prefilledExchangesUrls.push(...exchanges);
     }
     if (props.suggestedExchangeUrl) {
       prefilledExchangesUrls.push(props.suggestedExchangeUrl);
     }
-    if (prefilledExchangesUrls.length != 0) {
+    if (prefilledExchangesUrls.length !== 0) {
       this.url(prefilledExchangesUrls[0]);
       this.forceReserveUpdate();
     } else {
@@ -365,9 +355,9 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
   }
 
   renderFeeStatus() {
-    let rci = this.reserveCreationInfo();
+    const rci = this.reserveCreationInfo();
     if (rci) {
-      let totalCost = Amounts.add(rci.overhead, rci.withdrawFee).amount;
+      const totalCost = Amounts.add(rci.overhead, rci.withdrawFee).amount;
       let trustMessage;
       if (rci.isTrusted) {
         trustMessage = (
@@ -404,7 +394,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
       );
     }
     if (this.url() && !this.statusString()) {
-      let shortName = new URI(this.url()!).host();
+      const shortName = new URI(this.url()!).host();
       return (
         <i18n.Translate wrap="p">
           Waiting for a response from
@@ -432,7 +422,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
       <div>
         {this.renderFeeStatus()}
         <button className="pure-button button-success"
-                disabled={this.reserveCreationInfo() == null}
+                disabled={this.reserveCreationInfo() === null}
                 onClick={() => this.confirmReserve()}>
           {i18n.str`Accept fees and withdraw`}
         </button>
@@ -460,7 +450,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
   }
 
   renderSelect() {
-    let exchanges = (this.props.currencyRecord && 
this.props.currencyRecord.exchanges) || [];
+    const exchanges = (this.props.currencyRecord && 
this.props.currencyRecord.exchanges) || [];
     console.log(exchanges);
     return (
       <div>
@@ -478,7 +468,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
         {exchanges.length > 0 && (
           <div>
             <h2>Known Exchanges</h2>
-            {exchanges.map(e => (
+            {exchanges.map((e) => (
               <button className="pure-button button-success" onClick={() => 
this.select(e.baseUrl)}>
               Select <strong>{e.baseUrl}</strong>
               </button>
@@ -519,8 +509,8 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
   async forceReserveUpdate() {
     this.reserveCreationInfo(null);
     try {
-      let url = canonicalizeBaseUrl(this.url()!);
-      let r = await getReserveCreationInfo(url,
+      const url = canonicalizeBaseUrl(this.url()!);
+      const r = await getReserveCreationInfo(url,
                                            this.props.amount);
       console.log("get exchange info resolved");
       this.reserveCreationInfo(r);
@@ -530,7 +520,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
       if (e.hasOwnProperty("httpStatus")) {
         this.statusString(`Error: request failed with status ${e.httpStatus}`);
       } else if (e.hasOwnProperty("errorResponse")) {
-        let resp = e.errorResponse;
+        const resp = e.errorResponse;
         this.statusString(`Error: ${resp.error} (${resp.hint})`);
       }
     }
@@ -546,13 +536,13 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
         throw Error("empty response");
       }
       // FIXME: filter out types that bank/exchange don't have in common
-      let wireDetails = rci.wireInfo;
-      let filteredWireDetails: any = {};
-      for (let wireType in wireDetails) {
-        if (this.props.wt_types.findIndex((x) => x.toLowerCase() == 
wireType.toLowerCase()) < 0) {
+      const wireDetails = rci.wireInfo;
+      const filteredWireDetails: any = {};
+      for (const wireType in wireDetails) {
+        if (this.props.wt_types.findIndex((x) => x.toLowerCase() === 
wireType.toLowerCase()) < 0) {
           continue;
         }
-        let obj = Object.assign({}, wireDetails[wireType]);
+        const obj = Object.assign({}, wireDetails[wireType]);
         // The bank doesn't need to know about fees
         delete obj.fees;
         // Consequently the bank can't verify signatures anyway, so
@@ -563,15 +553,15 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
       }
       if (!rawResp.error) {
         const resp = CreateReserveResponse.checked(rawResp);
-        let q: {[name: string]: string|number} = {
-          wire_details: JSON.stringify(filteredWireDetails),
+        const q: {[name: string]: string|number} = {
+          amount_currency: amount.currency,
+          amount_fraction: amount.fraction,
+          amount_value: amount.value,
           exchange: resp.exchange,
           reserve_pub: resp.reservePub,
-          amount_value: amount.value,
-          amount_fraction: amount.fraction,
-          amount_currency: amount.currency,
+          wire_details: JSON.stringify(filteredWireDetails),
         };
-        let url = new URI(callback_url).addQuery(q);
+        const url = new URI(callback_url).addQuery(q);
         if (!url.is("absolute")) {
           throw Error("callback url is not absolute");
         }
@@ -582,7 +572,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
           i18n.str`Oops, something went wrong. The wallet responded with error 
status (${rawResp.error}).`);
       }
     };
-    chrome.runtime.sendMessage({type: 'create-reserve', detail: d}, cb);
+    chrome.runtime.sendMessage({type: "create-reserve", detail: d}, cb);
   }
 
   renderStatus(): any {
@@ -595,7 +585,7 @@ class ExchangeSelection extends 
ImplicitStateComponent<ExchangeSelectionProps> {
   }
 }
 
-export async function main() {
+async function main() {
   try {
     const url = new URI(document.location.href);
     const query: any = URI.parseQuery(url.query());
@@ -614,15 +604,15 @@ export async function main() {
       throw Error(i18n.str`Can't parse wire_types: ${e.message}`);
     }
 
-    let suggestedExchangeUrl = query.suggested_exchange_url;
-    let currencyRecord = await getCurrency(amount.currency);
+    const suggestedExchangeUrl = query.suggested_exchange_url;
+    const currencyRecord = await getCurrency(amount.currency);
 
-    let args = {
-      wt_types,
-      suggestedExchangeUrl,
-      callback_url,
+    const args = {
       amount,
+      callback_url,
       currencyRecord,
+      suggestedExchangeUrl,
+      wt_types,
     };
 
     ReactDOM.render(<ExchangeSelection {...args} />, document.getElementById(
diff --git a/src/webex/pages/error.tsx b/src/webex/pages/error.tsx
index f278bd22..829ea0c9 100644
--- a/src/webex/pages/error.tsx
+++ b/src/webex/pages/error.tsx
@@ -28,8 +28,6 @@ import * as React from "react";
 import * as ReactDOM from "react-dom";
 import URI = require("urijs");
 
-"use strict";
-
 interface ErrorProps {
   message: string;
 }
@@ -44,7 +42,7 @@ class ErrorView extends React.Component<ErrorProps, void> {
   }
 }
 
-export async function main() {
+async function main() {
   try {
     const url = new URI(document.location.href);
     const query: any = URI.parseQuery(url.query());
diff --git a/src/webex/pages/logs.tsx b/src/webex/pages/logs.tsx
index 0c533bfa..51f2cef3 100644
--- a/src/webex/pages/logs.tsx
+++ b/src/webex/pages/logs.tsx
@@ -20,7 +20,10 @@
  * @author Florian Dold
  */
 
-import {LogEntry, getLogs} from "../../logging";
+import {
+  LogEntry,
+  getLogs,
+} from "../../logging";
 
 import * as React from "react";
 import * as ReactDOM from "react-dom";
@@ -31,7 +34,7 @@ interface LogViewProps {
 
 class LogView extends React.Component<LogViewProps, void> {
   render(): JSX.Element {
-    let e = this.props.log;
+    const e = this.props.log;
     return (
       <div className="tree-item">
         <ul>
@@ -60,19 +63,19 @@ class Logs extends React.Component<any, LogsState> {
   }
 
   async update() {
-    let logs = await getLogs();
+    const logs = await getLogs();
     this.setState({logs});
   }
 
   render(): JSX.Element {
-    let logs = this.state.logs;
+    const logs = this.state.logs;
     if (!logs) {
       return <span>...</span>;
     }
     return (
       <div className="tree-item">
         Logs:
-        {logs.map(e => <LogView log={e} />)}
+        {logs.map((e) => <LogView log={e} />)}
       </div>
     );
   }
diff --git a/src/webex/pages/payback.tsx b/src/webex/pages/payback.tsx
index 7bcc581d..e10da7b0 100644
--- a/src/webex/pages/payback.tsx
+++ b/src/webex/pages/payback.tsx
@@ -21,25 +21,28 @@
  */
 
 
+/**
+ * Imports.
+ */
 import { amountToPretty, getTalerStampDate } from "../../helpers";
 import {
-  ExchangeRecord,
-  ExchangeForCurrencyRecord,
-  DenominationRecord,
   AuditorRecord,
-  CurrencyRecord,
-  ReserveRecord,
   CoinRecord,
-  PreCoinRecord,
+  CurrencyRecord,
   Denomination,
+  DenominationRecord,
+  ExchangeForCurrencyRecord,
+  ExchangeRecord,
+  PreCoinRecord,
+  ReserveRecord,
   WalletBalance,
 } from "../../types";
 
 import { ImplicitStateComponent, StateHolder } from "../components";
 import {
   getCurrencies,
-  updateCurrency,
   getPaybackReserves,
+  updateCurrency,
   withdrawPaybackReserve,
 } from "../wxApi";
 
@@ -47,10 +50,10 @@ import * as React from "react";
 import * as ReactDOM from "react-dom";
 
 class Payback extends ImplicitStateComponent<any> {
-  reserves: StateHolder<ReserveRecord[]|null> = this.makeState(null);
+  private reserves: StateHolder<ReserveRecord[]|null> = this.makeState(null);
   constructor() {
     super();
-    let port = chrome.runtime.connect();
+    const port = chrome.runtime.connect();
     port.onMessage.addListener((msg: any) => {
       if (msg.notify) {
         console.log("got notified");
@@ -61,25 +64,25 @@ class Payback extends ImplicitStateComponent<any> {
   }
 
   async update() {
-    let reserves = await getPaybackReserves();
+    const reserves = await getPaybackReserves();
     this.reserves(reserves);
   }
 
   withdrawPayback(pub: string) {
-    withdrawPaybackReserve(pub); 
+    withdrawPaybackReserve(pub);
   }
 
   render(): JSX.Element {
-    let reserves = this.reserves();
+    const reserves = this.reserves();
     if (!reserves) {
       return <span>loading ...</span>;
     }
-    if (reserves.length == 0) {
+    if (reserves.length === 0) {
       return <span>No reserves with payback available.</span>;
     }
     return (
       <div>
-        {reserves.map(r => (
+        {reserves.map((r) => (
           <div>
             <h2>Reserve for ${amountToPretty(r.current_amount!)}</h2>
             <ul>
@@ -93,7 +96,7 @@ class Payback extends ImplicitStateComponent<any> {
   }
 }
 
-export function main() {
+function main() {
   ReactDOM.render(<Payback />, document.getElementById("container")!);
 }
 
diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx
index f710156a..a1a3f6b2 100644
--- a/src/webex/pages/popup.tsx
+++ b/src/webex/pages/popup.tsx
@@ -22,18 +22,21 @@
  * @author Florian Dold
  */
 
-
-"use strict";
-
+/**
+ * Imports.
+ */
+import { amountToPretty } from "../../helpers";
+import * as i18n from "../../i18n";
 import {
   AmountJson,
   Amounts,
   WalletBalance,
-  WalletBalanceEntry
+  WalletBalanceEntry,
 } from "../../types";
-import { HistoryRecord, HistoryLevel } from "../../wallet";
-import { amountToPretty } from "../../helpers";
-import * as i18n from "../../i18n";
+import {
+  HistoryLevel,
+  HistoryRecord,
+} from "../../wallet";
 
 import { abbrev } from "../renderHtml";
 
@@ -42,18 +45,18 @@ import * as ReactDOM from "react-dom";
 import URI = require("urijs");
 
 function onUpdateNotification(f: () => void): () => void {
-  let port = chrome.runtime.connect({name: "notifications"});
-  let listener = (msg: any, port: any) => {
+  const port = chrome.runtime.connect({name: "notifications"});
+  const listener = () => {
     f();
   };
   port.onMessage.addListener(listener);
   return () => {
     port.onMessage.removeListener(listener);
-  }
+  };
 }
 
 
-class Router extends React.Component<any,any> {
+class Router extends React.Component<any, any> {
   static setRoute(s: string): void {
     window.location.hash = s;
   }
@@ -66,21 +69,21 @@ class Router extends React.Component<any,any> {
   static onRoute(f: any): () => void {
     Router.routeHandlers.push(f);
     return () => {
-      let i = Router.routeHandlers.indexOf(f);
+      const i = Router.routeHandlers.indexOf(f);
       this.routeHandlers = this.routeHandlers.splice(i, 1);
-    }
+    };
   }
 
-  static routeHandlers: any[] = [];
+  private static routeHandlers: any[] = [];
 
   componentWillMount() {
     console.log("router mounted");
     window.onhashchange = () => {
       this.setState({});
-      for (let f of Router.routeHandlers) {
+      for (const f of Router.routeHandlers) {
         f();
       }
-    }
+    };
   }
 
   componentWillUnmount() {
@@ -89,27 +92,27 @@ class Router extends React.Component<any,any> {
 
 
   render(): JSX.Element {
-    let route = window.location.hash.substring(1);
+    const route = window.location.hash.substring(1);
     console.log("rendering route", route);
     let defaultChild: React.ReactChild|null = null;
     let foundChild: React.ReactChild|null = null;
     React.Children.forEach(this.props.children, (child) => {
-      let childProps: any = (child as any).props;
+      const childProps: any = (child as any).props;
       if (!childProps) {
         return;
       }
-      if (childProps["default"]) {
+      if (childProps.default) {
         defaultChild = child;
       }
-      if (childProps["route"] == route) {
+      if (childProps.route === route) {
         foundChild = child;
       }
-    })
-    let child: React.ReactChild | null = foundChild || defaultChild;
+    });
+    const child: React.ReactChild | null = foundChild || defaultChild;
     if (!child) {
       throw Error("unknown route");
     }
-    Router.setRoute((child as any).props["route"]);
+    Router.setRoute((child as any).props.route);
     return <div>{child}</div>;
   }
 }
@@ -122,10 +125,10 @@ interface TabProps {
 
 function Tab(props: TabProps) {
   let cssClass = "";
-  if (props.target == Router.getRoute()) {
+  if (props.target === Router.getRoute()) {
     cssClass = "active";
   }
-  let onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
+  const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
     Router.setRoute(props.target);
     e.preventDefault();
   };
@@ -137,8 +140,8 @@ function Tab(props: TabProps) {
 }
 
 
-class WalletNavBar extends React.Component<any,any> {
-  cancelSubscription: any;
+class WalletNavBar extends React.Component<any, any> {
+  private cancelSubscription: any;
 
   componentWillMount() {
     this.cancelSubscription = Router.onRoute(() => {
@@ -171,21 +174,25 @@ class WalletNavBar extends React.Component<any,any> {
 
 
 function ExtensionLink(props: any) {
-  let onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
+  const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
     chrome.tabs.create({
-                         "url": chrome.extension.getURL(props.target)
-                       });
+      url: chrome.extension.getURL(props.target),
+    });
     e.preventDefault();
   };
   return (
     <a onClick={onClick} href={props.target}>
       {props.children}
-    </a>)
+    </a>
+  );
 }
 
 
-export function bigAmount(amount: AmountJson): JSX.Element {
-  let v = amount.value + amount.fraction / Amounts.fractionalBase;
+/**
+ * Render an amount as a large number with a small currency symbol.
+ */
+function bigAmount(amount: AmountJson): JSX.Element {
+  const v = amount.value + amount.fraction / Amounts.fractionalBase;
   return (
     <span>
       <span style={{fontSize: "300%"}}>{v}</span>
@@ -196,10 +203,10 @@ export function bigAmount(amount: AmountJson): 
JSX.Element {
 }
 
 class WalletBalanceView extends React.Component<any, any> {
-  balance: WalletBalance;
-  gotError = false;
-  canceler: (() => void) | undefined = undefined;
-  unmount = false;
+  private balance: WalletBalance;
+  private gotError = false;
+  private canceler: (() => void) | undefined = undefined;
+  private unmount = false;
 
   componentWillMount() {
     this.canceler = onUpdateNotification(() => this.updateBalance());
@@ -233,7 +240,7 @@ class WalletBalanceView extends React.Component<any, any> {
   }
 
   renderEmpty(): JSX.Element {
-    let helpLink = (
+    const helpLink = (
       <ExtensionLink target="/src/webex/pages/help/empty-wallet.html">
         {i18n.str`help`}
       </ExtensionLink>
@@ -281,20 +288,20 @@ class WalletBalanceView extends React.Component<any, any> 
{
       );
     }
 
-    let l = [incoming, payment].filter((x) => x !== undefined);
-    if (l.length == 0) {
+    const l = [incoming, payment].filter((x) => x !== undefined);
+    if (l.length === 0) {
       return <span />;
     }
 
-    if (l.length == 1) {
-      return <span>({l})</span>
+    if (l.length === 1) {
+      return <span>({l})</span>;
     }
     return <span>({l[0]}, {l[1]})</span>;
 
   }
 
   render(): JSX.Element {
-    let wallet = this.balance;
+    const wallet = this.balance;
     if (this.gotError) {
       return i18n.str`Error: could not retrieve balance information.`;
     }
@@ -303,9 +310,9 @@ class WalletBalanceView extends React.Component<any, any> {
     }
     console.log(wallet);
     let paybackAvailable = false;
-    let listing = Object.keys(wallet).map((key) => {
-      let entry: WalletBalanceEntry = wallet[key];
-      if (entry.paybackAmount.value != 0 || entry.paybackAmount.fraction != 0) 
{
+    const listing = Object.keys(wallet).map((key) => {
+      const entry: WalletBalanceEntry = wallet[key];
+      if (entry.paybackAmount.value !== 0 || entry.paybackAmount.fraction !== 
0) {
         paybackAvailable = true;
       }
       return (
@@ -316,10 +323,10 @@ class WalletBalanceView extends React.Component<any, any> 
{
         </p>
       );
     });
-    let link = chrome.extension.getURL("/src/webex/pages/auditors.html");
-    let linkElem = <a className="actionLink" href={link} 
target="_blank">Trusted Auditors and Exchanges</a>;
-    let paybackLink = chrome.extension.getURL("/src/webex/pages/payback.html");
-    let paybackLinkElem = <a className="actionLink" href={link} 
target="_blank">Trusted Auditors and Exchanges</a>;
+    const link = chrome.extension.getURL("/src/webex/pages/auditors.html");
+    const linkElem = <a className="actionLink" href={link} 
target="_blank">Trusted Auditors and Exchanges</a>;
+    const paybackLink = 
chrome.extension.getURL("/src/webex/pages/payback.html");
+    const paybackLinkElem = <a className="actionLink" href={link} 
target="_blank">Trusted Auditors and Exchanges</a>;
     return (
       <div>
         {listing.length > 0 ? listing : this.renderEmpty()}
@@ -339,13 +346,15 @@ function formatHistoryItem(historyItem: HistoryRecord) {
     case "create-reserve":
       return (
         <i18n.Translate wrap="p">
-          Bank requested reserve (<span>{abbrev(d.reservePub)}</span>) for 
<span>{amountToPretty(d.requestedAmount)}</span>.
+          Bank requested reserve (<span>{abbrev(d.reservePub)}</span>) for
+          {" "}
+          <span>{amountToPretty(d.requestedAmount)}</span>.
         </i18n.Translate>
       );
     case "confirm-reserve": {
       // FIXME: eventually remove compat fix
-      let exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() : 
"??";
-      let pub = abbrev(d.reservePub);
+      const exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() 
: "??";
+      const pub = abbrev(d.reservePub);
       return (
         <i18n.Translate wrap="p">
           Started to withdraw
@@ -355,9 +364,9 @@ function formatHistoryItem(historyItem: HistoryRecord) {
       );
     }
     case "offer-contract": {
-      let link = chrome.extension.getURL("view-contract.html");
-      let linkElem = <a href={link}>{abbrev(d.contractHash)}</a>;
-      let merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
+      const link = chrome.extension.getURL("view-contract.html");
+      const linkElem = <a href={link}>{abbrev(d.contractHash)}</a>;
+      const merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
       return (
         <i18n.Translate wrap="p">
           Merchant <em>{abbrev(d.merchantName, 15)}</em> offered contract <a 
href={link}>{abbrev(d.contractHash)}</a>;
@@ -365,9 +374,9 @@ function formatHistoryItem(historyItem: HistoryRecord) {
       );
     }
     case "depleted-reserve": {
-      let exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() : 
"??";
-      let amount = amountToPretty(d.requestedAmount);
-      let pub = abbrev(d.reservePub);
+      const exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() 
: "??";
+      const amount = amountToPretty(d.requestedAmount);
+      const pub = abbrev(d.reservePub);
       return (
         <i18n.Translate wrap="p">
           Withdrew <span>{amount}</span> from <span>{exchange}</span> 
(<span>{pub}</span>).
@@ -375,12 +384,14 @@ function formatHistoryItem(historyItem: HistoryRecord) {
       );
     }
     case "pay": {
-      let url = d.fulfillmentUrl;
-      let merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
-      let fulfillmentLinkElem = <a href={url} onClick={openTab(url)}>view 
product</a>;
+      const url = d.fulfillmentUrl;
+      const merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
+      const fulfillmentLinkElem = <a href={url} onClick={openTab(url)}>view 
product</a>;
       return (
         <i18n.Translate wrap="p">
-          Paid <span>{amountToPretty(d.amount)}</span> to merchant 
<span>{merchantElem}</span>.  (<span>{fulfillmentLinkElem}</span>)
+          Paid <span>{amountToPretty(d.amount)}</span> to merchant 
<span>{merchantElem}</span>.
+          {" "}
+          (<span>{fulfillmentLinkElem}</span>)
         </i18n.Translate>
       );
     }
@@ -391,9 +402,9 @@ function formatHistoryItem(historyItem: HistoryRecord) {
 
 
 class WalletHistory extends React.Component<any, any> {
-  myHistory: any[];
-  gotError = false;
-  unmounted = false;
+  private myHistory: any[];
+  private gotError = false;
+  private unmounted = false;
 
   componentWillMount() {
     this.update();
@@ -426,7 +437,7 @@ class WalletHistory extends React.Component<any, any> {
 
   render(): JSX.Element {
     console.log("rendering history");
-    let history: HistoryRecord[] = this.myHistory;
+    const history: HistoryRecord[] = this.myHistory;
     if (this.gotError) {
       return i18n.str`Error: could not retrieve event history`;
     }
@@ -436,18 +447,18 @@ class WalletHistory extends React.Component<any, any> {
       return <span />;
     }
 
-    let subjectMemo: {[s: string]: boolean} = {};
-    let listing: any[] = [];
-    for (let record of history.reverse()) {
+    const subjectMemo: {[s: string]: boolean} = {};
+    const listing: any[] = [];
+    for (const record of history.reverse()) {
       if (record.subjectId && subjectMemo[record.subjectId]) {
         continue;
       }
-      if (record.level != undefined && record.level < HistoryLevel.User) {
+      if (record.level !== undefined && record.level < HistoryLevel.User) {
         continue;
       }
       subjectMemo[record.subjectId as string] = true;
 
-      let item = (
+      const item = (
         <div className="historyItem">
           <div className="historyDate">
             {(new Date(record.timestamp)).toString()}
@@ -462,7 +473,7 @@ class WalletHistory extends React.Component<any, any> {
     if (listing.length > 0) {
       return <div className="container">{listing}</div>;
     }
-    return <p>{i18n.str`Your wallet has no events recorded.`}</p>
+    return <p>{i18n.str`Your wallet has no events recorded.`}</p>;
   }
 
 }
@@ -513,24 +524,24 @@ function WalletDebug(props: any) {
 
 
 function openExtensionPage(page: string) {
-  return function() {
+  return () => {
     chrome.tabs.create({
-      "url": chrome.extension.getURL(page)
+      url: chrome.extension.getURL(page),
     });
-  }
+  };
 }
 
 
 function openTab(page: string) {
-  return function() {
+  return () => {
     chrome.tabs.create({
-      "url": page
+      url: page,
     });
-  }
+  };
 }
 
 
-let el = (
+const el = (
   <div>
     <WalletNavBar />
     <div style={{margin: "1em"}}>
@@ -545,4 +556,4 @@ let el = (
 
 document.addEventListener("DOMContentLoaded", () => {
   ReactDOM.render(el, document.getElementById("content")!);
-})
+});
diff --git a/src/webex/pages/tree.tsx b/src/webex/pages/tree.tsx
index ddf8f2db..850a3c46 100644
--- a/src/webex/pages/tree.tsx
+++ b/src/webex/pages/tree.tsx
@@ -34,9 +34,15 @@ import {
 
 import { ImplicitStateComponent, StateHolder } from "../components";
 import {
-  getReserves, getExchanges, getCoins, getPreCoins,
-  refresh, getDenoms, payback,
+  getCoins,
+  getDenoms,
+  getExchanges,
+  getPreCoins,
+  getReserves,
+  payback,
+  refresh,
 } from "../wxApi";
+
 import * as React from "react";
 import * as ReactDOM from "react-dom";
 
@@ -46,7 +52,7 @@ interface ReserveViewProps {
 
 class ReserveView extends React.Component<ReserveViewProps, void> {
   render(): JSX.Element {
-    let r: ReserveRecord = this.props.reserve;
+    const r: ReserveRecord = this.props.reserve;
     return (
       <div className="tree-item">
         <ul>
@@ -71,11 +77,11 @@ interface ToggleProps {
 
 class Toggle extends ImplicitStateComponent<ToggleProps> {
   renderButton() {
-    let show = () => {
+    const show = () => {
       this.props.expanded(true);
       this.setState({});
     };
-    let hide = () => {
+    const hide = () => {
       this.props.expanded(false);
       this.setState({});
     };
@@ -104,7 +110,7 @@ interface RefreshDialogProps {
 }
 
 class RefreshDialog extends ImplicitStateComponent<RefreshDialogProps> {
-  refreshRequested = this.makeState<boolean>(false);
+  private refreshRequested = this.makeState<boolean>(false);
   render(): JSX.Element {
     if (!this.refreshRequested()) {
       return (
@@ -125,7 +131,7 @@ class RefreshDialog extends 
ImplicitStateComponent<RefreshDialogProps> {
 
 class CoinView extends React.Component<CoinViewProps, void> {
   render() {
-    let c = this.props.coin;
+    const c = this.props.coin;
     return (
       <div className="tree-item">
         <ul>
@@ -143,14 +149,13 @@ class CoinView extends React.Component<CoinViewProps, 
void> {
 }
 
 
-
 interface PreCoinViewProps {
   precoin: PreCoinRecord;
 }
 
 class PreCoinView extends React.Component<PreCoinViewProps, void> {
   render() {
-    let c = this.props.precoin;
+    const c = this.props.precoin;
     return (
       <div className="tree-item">
         <ul>
@@ -166,8 +171,8 @@ interface CoinListProps {
 }
 
 class CoinList extends ImplicitStateComponent<CoinListProps> {
-  coins = this.makeState<CoinRecord[] | null>(null);
-  expanded = this.makeState<boolean>(false);
+  private coins = this.makeState<CoinRecord[] | null>(null);
+  private expanded = this.makeState<boolean>(false);
 
   constructor(props: CoinListProps) {
     super(props);
@@ -175,7 +180,7 @@ class CoinList extends 
ImplicitStateComponent<CoinListProps> {
   }
 
   async update(props: CoinListProps) {
-    let coins = await getCoins(props.exchangeBaseUrl);
+    const coins = await getCoins(props.exchangeBaseUrl);
     this.coins(coins);
   }
 
@@ -205,8 +210,8 @@ interface PreCoinListProps {
 }
 
 class PreCoinList extends ImplicitStateComponent<PreCoinListProps> {
-  precoins = this.makeState<PreCoinRecord[] | null>(null);
-  expanded = this.makeState<boolean>(false);
+  private precoins = this.makeState<PreCoinRecord[] | null>(null);
+  private expanded = this.makeState<boolean>(false);
 
   constructor(props: PreCoinListProps) {
     super(props);
@@ -214,7 +219,7 @@ class PreCoinList extends 
ImplicitStateComponent<PreCoinListProps> {
   }
 
   async update() {
-    let precoins = await getPreCoins(this.props.exchangeBaseUrl);
+    const precoins = await getPreCoins(this.props.exchangeBaseUrl);
     this.precoins(precoins);
   }
 
@@ -243,8 +248,8 @@ interface ExpanderTextProps {
 }
 
 class ExpanderText extends ImplicitStateComponent<ExpanderTextProps> {
-  expanded = this.makeState<boolean>(false);
-  textArea: any = undefined;
+  private expanded = this.makeState<boolean>(false);
+  private textArea: any = undefined;
 
   componentDidUpdate() {
     if (this.expanded() && this.textArea) {
@@ -258,10 +263,10 @@ class ExpanderText extends 
ImplicitStateComponent<ExpanderTextProps> {
       return (
         <span onClick={() => { this.expanded(true); }}>
           {(this.props.text.length <= 10)
-            ?  this.props.text 
+            ?  this.props.text
             : (
                 <span>
-                  {this.props.text.substring(0,10)}
+                  {this.props.text.substring(0, 10)}
                   <span style={{textDecoration: "underline"}}>...</span>
                 </span>
               )
@@ -282,8 +287,8 @@ class ExpanderText extends 
ImplicitStateComponent<ExpanderTextProps> {
 }
 
 class DenominationList extends ImplicitStateComponent<DenominationListProps> {
-  expanded = this.makeState<boolean>(false);
-  denoms = this.makeState<undefined|DenominationRecord[]>(undefined);
+  private expanded = this.makeState<boolean>(false);
+  private denoms = this.makeState<undefined|DenominationRecord[]>(undefined);
 
   constructor(props: DenominationListProps) {
     super(props);
@@ -291,7 +296,7 @@ class DenominationList extends 
ImplicitStateComponent<DenominationListProps> {
   }
 
   async update() {
-    let d = await getDenoms(this.props.exchange.baseUrl);
+    const d = await getDenoms(this.props.exchange.baseUrl);
     this.denoms(d);
   }
 
@@ -316,7 +321,7 @@ class DenominationList extends 
ImplicitStateComponent<DenominationListProps> {
   }
 
   render(): JSX.Element {
-    let denoms = this.denoms()
+    const denoms = this.denoms();
     if (!denoms) {
       return (
         <div className="tree-item">
@@ -340,9 +345,10 @@ class DenominationList extends 
ImplicitStateComponent<DenominationListProps> {
   }
 }
 
+
 class ReserveList extends ImplicitStateComponent<ReserveListProps> {
-  reserves = this.makeState<ReserveRecord[] | null>(null);
-  expanded = this.makeState<boolean>(false);
+  private reserves = this.makeState<ReserveRecord[] | null>(null);
+  private expanded = this.makeState<boolean>(false);
 
   constructor(props: ReserveListProps) {
     super(props);
@@ -350,7 +356,7 @@ class ReserveList extends 
ImplicitStateComponent<ReserveListProps> {
   }
 
   async update() {
-    let reserves = await getReserves(this.props.exchangeBaseUrl);
+    const reserves = await getReserves(this.props.exchangeBaseUrl);
     this.reserves(reserves);
   }
 
@@ -376,7 +382,7 @@ interface ExchangeProps {
 
 class ExchangeView extends React.Component<ExchangeProps, void> {
   render(): JSX.Element {
-    let e = this.props.exchange;
+    const e = this.props.exchange;
     return (
       <div className="tree-item">
         <ul>
@@ -399,7 +405,7 @@ interface ExchangesListState {
 class ExchangesList extends React.Component<any, ExchangesListState> {
   constructor() {
     super();
-    let port = chrome.runtime.connect();
+    const port = chrome.runtime.connect();
     port.onMessage.addListener((msg: any) => {
       if (msg.notify) {
         console.log("got notified");
@@ -411,26 +417,26 @@ class ExchangesList extends React.Component<any, 
ExchangesListState> {
   }
 
   async update() {
-    let exchanges = await getExchanges();
+    const exchanges = await getExchanges();
     console.log("exchanges: ", exchanges);
     this.setState({ exchanges });
   }
 
   render(): JSX.Element {
-    let exchanges = this.state.exchanges;
+    const exchanges = this.state.exchanges;
     if (!exchanges) {
       return <span>...</span>;
     }
     return (
       <div className="tree-item">
         Exchanges ({exchanges.length.toString()}):
-        {exchanges.map(e => <ExchangeView exchange={e} />)}
+        {exchanges.map((e) => <ExchangeView exchange={e} />)}
       </div>
     );
   }
 }
 
-export function main() {
+function main() {
   ReactDOM.render(<ExchangesList />, document.getElementById("container")!);
 }
 
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index 440cd578..d6f923aa 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -24,17 +24,19 @@
 /**
  * Imports.
  */
+import { amountToPretty } from "../helpers";
+import * as i18n from "../i18n";
 import {
   AmountJson,
   Amounts,
   Contract,
 } from "../types";
-import * as i18n from "../i18n";
-import { amountToPretty } from "../helpers";
 
 import * as React from "react";
 
-
+/**
+ * Render contract terms for the end user to view.
+ */
 export function renderContract(contract: Contract): JSX.Element {
   let merchantName;
   if (contract.merchant && contract.merchant.name) {
@@ -42,7 +44,7 @@ export function renderContract(contract: Contract): 
JSX.Element {
   } else {
     merchantName = <strong>(pub: {contract.merchant_pub})</strong>;
   }
-  let amount = <strong>{amountToPretty(contract.amount)}</strong>;
+  const amount = <strong>{amountToPretty(contract.amount)}</strong>;
 
   return (
     <div>
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index e5a50240..c120f34e 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -24,10 +24,13 @@
  */
 import {
   AmountJson,
+  CheckPayResult,
+  ConfirmPayResult,
   CoinRecord,
   CurrencyRecord,
   DenominationRecord,
   ExchangeRecord,
+  OfferRecord,
   PreCoinRecord,
   ReserveCreationInfo,
   ReserveRecord,
@@ -172,3 +175,26 @@ export async function refresh(coinPub: string): 
Promise<void> {
 export async function payback(coinPub: string): Promise<void> {
   return await callBackend("payback-coin", { coinPub });
 }
+
+/**
+ * Get an offer stored in the wallet by its offer id.
+ * Note that the numeric offer id is not to be confused with
+ * the string order_id from the contract terms.
+ */
+export async function getOffer(offerId: number) {
+  return await callBackend("get-offer", { offerId });
+}
+
+/**
+ * Check if payment is possible or already done.
+ */
+export async function checkPay(offer: OfferRecord): Promise<CheckPayResult> {
+  return await callBackend("check-pay", { offer });
+}
+
+/**
+ * Pay for an offer.
+ */
+export async function confirmPay(offer: OfferRecord): 
Promise<ConfirmPayResult> {
+  return await callBackend("confirm-pay", { offer });
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 2579bc31..c7aa34a9 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -35,12 +35,12 @@ import {
   AmountJson,
   Contract,
   Notifier,
+  OfferRecord,
 } from "../types";
 import {
   Badge,
   ConfirmReserveRequest,
   CreateReserveRequest,
-  OfferRecord,
   Stores,
   Wallet,
 } from "../wallet";
diff --git a/webpack.config.js b/webpack.config.js
index 49a7b865..d86379d5 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -33,6 +33,9 @@ module.exports = function (env) {
   if (env.prod) {
     base.plugins.push(new webpack.optimize.UglifyJsPlugin());
     base.plugins.push(new webpack.LoaderOptionsPlugin({minimize: true}));
+    base.plugins.push(new webpack.DefinePlugin({
+      "process.env.NODE_ENV": JSON.stringify("production")
+    }));
   }
   const configWebWorker = {
     entry: {"cryptoWorker": "./src/crypto/cryptoWorker.ts"},

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]