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: add linting rul


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] branch master updated: add linting rules and fix them
Date: Sun, 28 May 2017 13:46:53 +0200

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 08bd3dc0 add linting rules and fix them
08bd3dc0 is described below

commit 08bd3dc0e8a3c2370e4e8abbaa241eaafc144f4c
Author: Florian Dold <address@hidden>
AuthorDate: Sun May 28 01:10:54 2017 +0200

    add linting rules and fix them
---
 Makefile                         |   2 +-
 src/checkable.ts                 | 146 +++----
 src/chromeBadge.ts               |  39 +-
 src/components.ts                |   2 +-
 src/content_scripts/notify.ts    | 155 +++----
 src/crypto/cryptoApi-test.ts     | 126 +++---
 src/crypto/cryptoApi.ts          |  67 ++--
 src/crypto/cryptoWorker.ts       | 214 +++++-----
 src/crypto/emscInterface-test.ts | 109 +++--
 src/crypto/emscInterface.ts      | 384 +++++++-----------
 src/crypto/emscLoader.d.ts       |  12 +-
 src/crypto/nodeWorker.ts         |   5 +-
 src/crypto/nodeWorkerEntry.ts    |  38 +-
 src/helpers-test.ts              |  19 +-
 src/helpers.ts                   |  28 +-
 src/http.ts                      |  12 +-
 src/logging.ts                   |  96 +++--
 src/pages/show-db.ts             |  34 +-
 src/query.ts                     | 241 ++++++-----
 src/timer.ts                     |   2 +-
 src/types-test.ts                |  75 ++--
 src/types.ts                     |  66 +--
 src/wallet-test.ts               |  93 +++--
 src/wallet.ts                    | 842 ++++++++++++++++++++-------------------
 src/wxApi.ts                     |  13 +-
 src/wxBackend.ts                 | 263 ++++++------
 tslint.json                      |  21 +-
 27 files changed, 1612 insertions(+), 1492 deletions(-)

diff --git a/Makefile b/Makefile
index 362f5f6f..444bfdcf 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ coverage: tsc yarn-install
 
 .PHONY: lint
 lint: tsc yarn-install
-       $(tslint) --type-check --project tsconfig.json -t verbose 'src/**/*.ts'
+       $(tslint) --type-check -e src/i18n/strings.ts --project tsconfig.json 
-t verbose 'src/**/*.ts'
 
 .PHONY: yarn-install
 i18n: yarn-install
diff --git a/src/checkable.ts b/src/checkable.ts
index 1b6e371f..802d8f32 100644
--- a/src/checkable.ts
+++ b/src/checkable.ts
@@ -40,7 +40,7 @@
  */
 export namespace Checkable {
 
-  type Path = (number | string)[];
+  type Path = Array<number | string>;
 
   interface SchemaErrorConstructor {
     new (err: string): SchemaError;
@@ -67,22 +67,22 @@ export namespace Checkable {
     props: Prop[];
   }
 
-  export let SchemaError = (function SchemaError(this: any, message: string) {
-    let that: any = this as any;
-    that.name = 'SchemaError';
+  export const SchemaError = (function SchemaError(this: any, message: string) 
{
+    const that: any = this as any;
+    that.name = "SchemaError";
     that.message = message;
-    that.stack = (<any>new Error()).stack;
+    that.stack = (new Error() as any).stack;
   }) as any as SchemaErrorConstructor;
 
 
-  SchemaError.prototype = new Error;
+  SchemaError.prototype = new Error();
 
   /**
    * Classes that are checkable are annotated with this
    * checkable info symbol, which contains the information necessary
    * to check if they're valid.
    */
-  let checkableInfoSym = Symbol("checkableInfo");
+  const checkableInfoSym = Symbol("checkableInfo");
 
   /**
    * Get the current property list for a checkable type.
@@ -138,7 +138,7 @@ export namespace Checkable {
       throw new SchemaError(`array expected for ${path}, got ${typeof target} 
instead`);
     }
     for (let i = 0; i < target.length; i++) {
-      let v = target[i];
+      const v = target[i];
       prop.elementChecker(v, prop.elementProp, path.concat([i]));
     }
     return target;
@@ -148,9 +148,9 @@ export namespace Checkable {
     if (typeof target !== "object") {
       throw new SchemaError(`expected  object for ${path}, got ${typeof 
target} instead`);
     }
-    for (let key in target) {
+    for (const key in target) {
       prop.keyProp.checker(key, prop.keyProp, path.concat([key]));
-      let value = target[key];
+      const value = target[key];
       prop.valueProp.checker(value, prop.valueProp, path.concat([key]));
     }
   }
@@ -166,35 +166,35 @@ export namespace Checkable {
 
 
   function checkValue(target: any, prop: Prop, path: Path): any {
-    let type = prop.type;
+    const type = prop.type;
     if (!type) {
       throw Error(`assertion failed (prop is ${JSON.stringify(prop)})`);
     }
-    let v = target;
+    const v = target;
     if (!v || typeof v !== "object") {
       throw new SchemaError(
         `expected object for ${path.join(".")}, got ${typeof v} instead`);
     }
-    let props = type.prototype[checkableInfoSym].props;
-    let remainingPropNames = new Set(Object.getOwnPropertyNames(v));
-    let obj = new type();
-    for (let prop of props) {
-      if (!remainingPropNames.has(prop.propertyKey)) {
-        if (prop.optional) {
+    const props = type.prototype[checkableInfoSym].props;
+    const remainingPropNames = new Set(Object.getOwnPropertyNames(v));
+    const obj = new type();
+    for (const innerProp of props) {
+      if (!remainingPropNames.has(innerProp.propertyKey)) {
+        if (innerProp.optional) {
           continue;
         }
-        throw new SchemaError(`Property ${prop.propertyKey} missing on 
${path}`);
+        throw new SchemaError(`Property ${innerProp.propertyKey} missing on 
${path}`);
       }
-      if (!remainingPropNames.delete(prop.propertyKey)) {
+      if (!remainingPropNames.delete(innerProp.propertyKey)) {
         throw new SchemaError("assertion failed");
       }
-      let propVal = v[prop.propertyKey];
-      obj[prop.propertyKey] = prop.checker(propVal,
-        prop,
-        path.concat([prop.propertyKey]));
+      const propVal = v[innerProp.propertyKey];
+      obj[innerProp.propertyKey] = innerProp.checker(propVal,
+        innerProp,
+        path.concat([innerProp.propertyKey]));
     }
 
-    if (!prop.extraAllowed && remainingPropNames.size != 0) {
+    if (!prop.extraAllowed && remainingPropNames.size !== 0) {
       throw new SchemaError("superfluous properties " + 
JSON.stringify(Array.from(
         remainingPropNames.values())));
     }
@@ -210,14 +210,14 @@ export namespace Checkable {
   export function Class(opts: {extra?: boolean, validate?: boolean} = {}) {
     return (target: any) => {
       target.checked = (v: any) => {
-        let cv = checkValue(v, {
+        const cv = checkValue(v, {
+          checker: checkValue,
+          extraAllowed: !!opts.extra,
           propertyKey: "(root)",
           type: target,
-          extraAllowed: !!opts.extra,
-          checker: checkValue
         }, ["(root)"]);
         if (opts.validate) {
-          let instance = new target();
+          const instance = new target();
           if (typeof instance.validate !== "function") {
             throw Error("invalid Checkable annotion: validate method 
required");
           }
@@ -227,7 +227,7 @@ export namespace Checkable {
         return cv;
       };
       return target;
-    }
+    };
   }
 
 
@@ -238,12 +238,12 @@ export namespace Checkable {
     if (!type) {
       throw Error("Type does not exist yet (wrong order of definitions?)");
     }
-    function deco(target: Object, propertyKey: string | symbol): void {
-      let chk = getCheckableInfo(target);
+    function deco(target: object, propertyKey: string | symbol): void {
+      const chk = getCheckableInfo(target);
       chk.props.push({
-        propertyKey: propertyKey,
         checker: checkValue,
-        type: type
+        propertyKey,
+        type,
       });
     }
 
@@ -256,20 +256,20 @@ export namespace Checkable {
    * an annotation for a list of strings.
    */
   export function List(type: any) {
-    let stub = {};
+    const stub = {};
     type(stub, "(list-element)");
-    let elementProp = getCheckableInfo(stub).props[0];
-    let elementChecker = elementProp.checker;
+    const elementProp = getCheckableInfo(stub).props[0];
+    const elementChecker = elementProp.checker;
     if (!elementChecker) {
       throw Error("assertion failed");
     }
-    function deco(target: Object, propertyKey: string | symbol): void {
-      let chk = getCheckableInfo(target);
+    function deco(target: object, propertyKey: string | symbol): void {
+      const chk = getCheckableInfo(target);
       chk.props.push({
+        checker: checkList,
         elementChecker,
         elementProp,
-        propertyKey: propertyKey,
-        checker: checkList,
+        propertyKey,
       });
     }
 
@@ -282,25 +282,25 @@ export namespace Checkable {
    * one for the key type and one for the value type.
    */
   export function Map(keyType: any, valueType: any) {
-    let keyStub = {};
+    const keyStub = {};
     keyType(keyStub, "(map-key)");
-    let keyProp = getCheckableInfo(keyStub).props[0];
+    const keyProp = getCheckableInfo(keyStub).props[0];
     if (!keyProp) {
       throw Error("assertion failed");
     }
-    let valueStub = {};
+    const valueStub = {};
     valueType(valueStub, "(map-value)");
-    let valueProp = getCheckableInfo(valueStub).props[0];
+    const valueProp = getCheckableInfo(valueStub).props[0];
     if (!valueProp) {
       throw Error("assertion failed");
     }
-    function deco(target: Object, propertyKey: string | symbol): void {
-      let chk = getCheckableInfo(target);
+    function deco(target: object, propertyKey: string | symbol): void {
+      const chk = getCheckableInfo(target);
       chk.props.push({
+        checker: checkMap,
         keyProp,
+        propertyKey,
         valueProp,
-        propertyKey: propertyKey,
-        checker: checkMap,
       });
     }
 
@@ -312,21 +312,21 @@ export namespace Checkable {
    * Makes another annotation optional, for example 
address@hidden(Checkable.Number)`.
    */
   export function Optional(type: any) {
-    let stub = {};
+    const stub = {};
     type(stub, "(optional-element)");
-    let elementProp = getCheckableInfo(stub).props[0];
-    let elementChecker = elementProp.checker;
+    const elementProp = getCheckableInfo(stub).props[0];
+    const elementChecker = elementProp.checker;
     if (!elementChecker) {
       throw Error("assertion failed");
     }
-    function deco(target: Object, propertyKey: string | symbol): void {
-      let chk = getCheckableInfo(target);
+    function deco(target: object, propertyKey: string | symbol): void {
+      const chk = getCheckableInfo(target);
       chk.props.push({
+        checker: checkOptional,
         elementChecker,
         elementProp,
-        propertyKey: propertyKey,
-        checker: checkOptional,
         optional: true,
+        propertyKey,
       });
     }
 
@@ -337,20 +337,20 @@ export namespace Checkable {
   /**
    * Target property must be a number.
    */
-  export function Number(target: Object, propertyKey: string | symbol): void {
-    let chk = getCheckableInfo(target);
-    chk.props.push({ propertyKey: propertyKey, checker: checkNumber });
+  export function Number(target: object, propertyKey: string | symbol): void {
+    const chk = getCheckableInfo(target);
+    chk.props.push({checker: checkNumber, propertyKey});
   }
 
 
   /**
    * Target property must be an arbitary object.
    */
-  export function AnyObject(target: Object, propertyKey: string | symbol): 
void {
-    let chk = getCheckableInfo(target);
+  export function AnyObject(target: object, propertyKey: string | symbol): 
void {
+    const chk = getCheckableInfo(target);
     chk.props.push({
-      propertyKey: propertyKey,
-      checker: checkAnyObject
+      checker: checkAnyObject,
+      propertyKey,
     });
   }
 
@@ -361,12 +361,12 @@ export namespace Checkable {
    * Not useful by itself, but in combination with higher-order annotations
    * such as List or Map.
    */
-  export function Any(target: Object, propertyKey: string | symbol): void {
-    let chk = getCheckableInfo(target);
+  export function Any(target: object, propertyKey: string | symbol): void {
+    const chk = getCheckableInfo(target);
     chk.props.push({
-      propertyKey: propertyKey,
       checker: checkAny,
-      optional: true
+      optional: true,
+      propertyKey,
     });
   }
 
@@ -374,16 +374,16 @@ export namespace Checkable {
   /**
    * Target property must be a string.
    */
-  export function String(target: Object, propertyKey: string | symbol): void {
-    let chk = getCheckableInfo(target);
-    chk.props.push({ propertyKey: propertyKey, checker: checkString });
+  export function String(target: object, propertyKey: string | symbol): void {
+    const chk = getCheckableInfo(target);
+    chk.props.push({ checker: checkString, propertyKey });
   }
 
   /**
    * Target property must be a boolean value.
    */
-  export function Boolean(target: Object, propertyKey: string | symbol): void {
-    let chk = getCheckableInfo(target);
-    chk.props.push({ propertyKey: propertyKey, checker: checkBoolean });
+  export function Boolean(target: object, propertyKey: string | symbol): void {
+    const chk = getCheckableInfo(target);
+    chk.props.push({ checker: checkBoolean, propertyKey });
   }
 }
diff --git a/src/chromeBadge.ts b/src/chromeBadge.ts
index 369a9522..13716a64 100644
--- a/src/chromeBadge.ts
+++ b/src/chromeBadge.ts
@@ -15,7 +15,7 @@
  */
 
 import {
-  Badge
+  Badge,
 } from "./wallet";
 
 
@@ -85,7 +85,7 @@ export class ChromeBadge implements Badge {
 
   constructor(window?: Window) {
     // Allow injecting another window for testing
-    let bg = window || chrome.extension.getBackgroundPage();
+    const bg = window || chrome.extension.getBackgroundPage();
     if (!bg) {
       throw Error("no window available");
     }
@@ -130,13 +130,11 @@ export class ChromeBadge implements Badge {
     this.ctx.lineWidth = 2.5;
     if (this.animationRunning) {
       /* Draw circle around the "T" with an opening of this.gapWidth */
-      this.ctx.arc(0, 0,
-                   this.canvas.width / 2 - 2, /* radius */
-                   this.rotationAngle / ChromeBadge.rotationAngleMax * Math.PI 
* 2,
-                   ((this.rotationAngle + ChromeBadge.rotationAngleMax - 
this.gapWidth) / ChromeBadge.rotationAngleMax) * Math.PI * 2,
-                   false);
-    }
-    else {
+      const aMax = ChromeBadge.rotationAngleMax;
+      const startAngle = this.rotationAngle / aMax * Math.PI * 2;
+      const stopAngle = ((this.rotationAngle + aMax - this.gapWidth) / aMax) * 
Math.PI * 2;
+      this.ctx.arc(0, 0, this.canvas.width / 2 - 2, /* radius */ startAngle, 
stopAngle, false);
+    } else {
       /* Draw full circle */
       this.ctx.arc(0, 0,
                    this.canvas.width / 2 - 2, /* radius */
@@ -149,12 +147,13 @@ export class ChromeBadge implements Badge {
     this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);
 
     // Allow running outside the extension for testing
+    // tslint:disable-next-line:no-string-literal
     if (window["chrome"] && window.chrome["browserAction"]) {
       try {
-        let imageData = this.ctx.getImageData(0,
-                                              0,
-                                              this.canvas.width,
-                                              this.canvas.height);
+        const imageData = this.ctx.getImageData(0,
+                                                0,
+                                                this.canvas.width,
+                                                this.canvas.height);
         chrome.browserAction.setIcon({imageData});
       } catch (e) {
         // Might fail if browser has over-eager canvas fingerprinting 
countermeasures.
@@ -168,20 +167,20 @@ export class ChromeBadge implements Badge {
       return;
     }
     this.animationRunning = true;
-    let start: number|undefined = undefined;
-    let step = (timestamp: number) => {
+    let start: number|undefined;
+    const step = (timestamp: number) => {
       if (!this.animationRunning) {
         return;
       }
       if (!start) {
         start = timestamp;
       }
-      let delta = (timestamp - start);
-      if (!this.isBusy && 0 == this.gapWidth) {
+      if (!this.isBusy && 0 === this.gapWidth) {
         // stop if we're close enough to origin
         this.rotationAngle = 0;
       } else {
-        this.rotationAngle = (this.rotationAngle + (timestamp - start) * 
ChromeBadge.rotationSpeed) % ChromeBadge.rotationAngleMax;
+        this.rotationAngle = (this.rotationAngle + (timestamp - start) *
+                              ChromeBadge.rotationSpeed) % 
ChromeBadge.rotationAngleMax;
       }
       if (this.isBusy) {
         if (this.gapWidth < ChromeBadge.openMax) {
@@ -190,15 +189,13 @@ export class ChromeBadge implements Badge {
         if (this.gapWidth > ChromeBadge.openMax) {
           this.gapWidth = ChromeBadge.openMax;
         }
-      }
-      else {
+      } else {
         if (this.gapWidth > 0) {
           this.gapWidth--;
           this.gapWidth *= ChromeBadge.closeSpeed;
         }
       }
 
-
       if (this.isBusy || this.gapWidth > 0) {
         start = timestamp;
         rAF(step);
diff --git a/src/components.ts b/src/components.ts
index bef3cff4..9d1127e9 100644
--- a/src/components.ts
+++ b/src/components.ts
@@ -17,7 +17,7 @@
 
 /**
  * General helper React components.
- * 
+ *
  * @author Florian Dold
  */
 
diff --git a/src/content_scripts/notify.ts b/src/content_scripts/notify.ts
index 64414e0b..733367a5 100644
--- a/src/content_scripts/notify.ts
+++ b/src/content_scripts/notify.ts
@@ -14,6 +14,7 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+// tslint:disable:no-unused-expression
 
 /**
  * Module that is injected into (all!) pages to allow them
@@ -55,9 +56,9 @@ interface Handler {
 const handlers: Handler[] = [];
 
 function hashContract(contract: string): Promise<string> {
-  let walletHashContractMsg = {
+  const walletHashContractMsg = {
+    detail: {contract},
     type: "hash-contract",
-    detail: {contract}
   };
   return new Promise<string>((resolve, reject) => {
     chrome.runtime.sendMessage(walletHashContractMsg, (resp: any) => {
@@ -72,8 +73,8 @@ function hashContract(contract: string): Promise<string> {
 
 function queryPayment(url: string): Promise<any> {
   const walletMsg = {
-    type: "query-payment",
     detail: { url },
+    type: "query-payment",
   };
   return new Promise((resolve, reject) => {
     chrome.runtime.sendMessage(walletMsg, (resp: any) => {
@@ -84,10 +85,10 @@ function queryPayment(url: string): Promise<any> {
 
 function putHistory(historyEntry: any): Promise<void> {
   const walletMsg = {
-    type: "put-history-entry",
     detail: {
       historyEntry,
     },
+    type: "put-history-entry",
   };
   return new Promise<void>((resolve, reject) => {
     chrome.runtime.sendMessage(walletMsg, (resp: any) => {
@@ -98,14 +99,14 @@ function putHistory(historyEntry: any): Promise<void> {
 
 function saveOffer(offer: any): Promise<number> {
   const walletMsg = {
-    type: "save-offer",
     detail: {
       offer: {
+        H_contract: offer.hash,
         contract: offer.data,
         merchant_sig: offer.sig,
-        H_contract: offer.hash,
-        offer_time: new Date().getTime() / 1000
+        offer_time: new Date().getTime() / 1000,
       },
+    type: "save-offer",
     },
   };
   return new Promise<number>((resolve, reject) => {
@@ -120,15 +121,13 @@ function saveOffer(offer: any): Promise<number> {
 }
 
 
-
-
 let sheet: CSSStyleSheet|null;
 
 function initStyle() {
   logVerbose && console.log("taking over styles");
   const name = "taler-presence-stylesheet";
   const content = "/* Taler stylesheet controlled by JS */";
-  let style = document.getElementById(name) as HTMLStyleElement|null; 
+  let style = document.getElementById(name) as HTMLStyleElement|null;
   if (!style) {
     style = document.createElement("style");
     // Needed by WebKit
@@ -170,7 +169,6 @@ function setStyles(installed: boolean) {
 }
 
 
-
 function handlePaymentResponse(walletResp: any) {
   /**
    * Handle a failed payment.
@@ -185,16 +183,16 @@ function handlePaymentResponse(walletResp: any) {
       console.log("pay-failed", {status: r.status, response: r.responseText});
     }
     function onTimeout() {
-      timeoutHandle = null
+      timeoutHandle = null;
       err();
     }
     talerPaymentFailed(walletResp.H_contract).then(() => {
-      if (timeoutHandle != null) {
+      if (timeoutHandle !== null) {
         clearTimeout(timeoutHandle);
         timeoutHandle = null;
       }
       err();
-    })
+    });
     timeoutHandle = window.setTimeout(onTimeout, 200);
   }
 
@@ -210,7 +208,7 @@ function handlePaymentResponse(walletResp: any) {
     r.open("post", walletResp.contract.pay_url);
     r.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
     r.send(JSON.stringify(walletResp.payReq));
-    r.onload = function() {
+    r.onload = () => {
       if (!r) {
         return;
       }
@@ -219,7 +217,7 @@ function handlePaymentResponse(walletResp: any) {
           const merchantResp = JSON.parse(r.responseText);
           logVerbose && console.log("got success from pay_url");
           talerPaymentSucceeded({H_contract: walletResp.H_contract, 
merchantSig: merchantResp.sig}).then(() => {
-            let nextUrl = walletResp.contract.fulfillment_url;
+            const nextUrl = walletResp.contract.fulfillment_url;
             logVerbose && console.log("taler-payment-succeeded done, going 
to", nextUrl);
             window.location.href = nextUrl;
             window.location.reload(true);
@@ -230,7 +228,7 @@ function handlePaymentResponse(walletResp: any) {
           break;
       }
       r = null;
-      if (timeoutHandle != null) {
+      if (timeoutHandle !== null) {
         clearTimeout(timeoutHandle!);
         timeoutHandle = null;
       }
@@ -262,7 +260,7 @@ function init() {
         initStyle();
         setStyles(true);
       };
-      if (document.readyState == "complete") {
+      if (document.readyState === "complete") {
         onload();
       } else {
         document.addEventListener("DOMContentLoaded", onload);
@@ -270,19 +268,19 @@ function init() {
     }
     registerHandlers();
     // Hack to know when the extension is unloaded
-    let port = chrome.runtime.connect();
+    const port = chrome.runtime.connect();
 
     port.onDisconnect.addListener(() => {
       logVerbose && console.log("chrome runtime disconnected, removing 
handlers");
       if (document.documentElement.getAttribute("data-taler-nojs")) {
         setStyles(false);
       }
-      for (let handler of handlers) {
+      for (const handler of handlers) {
         document.removeEventListener(handler.type, handler.listener);
       }
     });
 
-    if (resp && resp.type == "pay") {
+    if (resp && resp.type === "pay") {
       logVerbose && console.log("doing taler.pay with", resp.payDetail);
       talerPay(resp.payDetail).then(handlePaymentResponse);
       document.documentElement.style.visibility = "hidden";
@@ -290,9 +288,7 @@ function init() {
   });
 }
 
-interface HandlerFn {
-  (detail: any, sendResponse: (msg: any) => void): void;
-}
+type HandlerFn = (detail: any, sendResponse: (msg: any) => void) => void;
 
 function generateNonce(): Promise<string> {
   const walletMsg = {
@@ -306,35 +302,47 @@ function generateNonce(): Promise<string> {
 }
 
 function downloadContract(url: string, nonce: string): Promise<any> {
-  let parsed_url = new URI(url);
+  const parsed_url = new URI(url);
   url = parsed_url.setQuery({nonce}).href();
   // FIXME: include and check nonce!
   return new Promise((resolve, reject) => {
     const contract_request = new XMLHttpRequest();
-    console.log("downloading contract from '" + url + "'")
+    console.log("downloading contract from '" + url + "'");
     contract_request.open("GET", url, true);
-    contract_request.onload = function (e) {
-      if (contract_request.readyState == 4) {
-        if (contract_request.status == 200) {
+    contract_request.onload = (e) => {
+      if (contract_request.readyState === 4) {
+        if (contract_request.status === 200) {
           console.log("response text:",
                       contract_request.responseText);
-          var contract_wrapper = JSON.parse(contract_request.responseText);
+          const contract_wrapper = JSON.parse(contract_request.responseText);
           if (!contract_wrapper) {
             console.error("response text was invalid json");
-            let detail = {hint: "invalid json", status: 
contract_request.status, body: contract_request.responseText};
+            const detail = {
+              body: contract_request.responseText,
+              hint: "invalid json",
+              status: contract_request.status,
+            };
             reject(detail);
             return;
           }
           resolve(contract_wrapper);
         } else {
-          let detail = {hint: "contract download failed", status: 
contract_request.status, body: contract_request.responseText};
+          const detail = {
+            body: contract_request.responseText,
+            hint: "contract download failed",
+            status: contract_request.status,
+          };
           reject(detail);
           return;
         }
       }
     };
-    contract_request.onerror = function (e) {
-      let detail = {hint: "contract download failed", status: 
contract_request.status, body: contract_request.responseText};
+    contract_request.onerror = (e) => {
+      const detail = {
+        body: contract_request.responseText,
+        hint: "contract download failed",
+        status: contract_request.status,
+      };
       reject(detail);
       return;
     };
@@ -353,9 +361,9 @@ async function processProposal(proposal: any) {
     return;
   }
 
-  let contractHash = await hashContract(proposal.data);
+  const contractHash = await hashContract(proposal.data);
 
-  if (contractHash != proposal.hash) {
+  if (contractHash !== proposal.hash) {
     console.error("merchant-supplied contract hash is wrong");
     return;
   }
@@ -367,17 +375,17 @@ async function processProposal(proposal: any) {
     // bad contract / name not included
   }
 
-  let historyEntry = {
-    timestamp: (new Date).getTime(),
-    subjectId: `contract-${contractHash}`,
-    type: "offer-contract",
+  const historyEntry = {
     detail: {
       contractHash,
       merchantName,
-    }
+    },
+    subjectId: `contract-${contractHash}`,
+    timestamp: (new Date()).getTime(),
+    type: "offer-contract",
   };
   await putHistory(historyEntry);
-  let offerId = await saveOffer(proposal);
+  const offerId = await saveOffer(proposal);
 
   const uri = new URI(chrome.extension.getURL(
     "/src/pages/confirm-contract.html"));
@@ -391,17 +399,17 @@ async function processProposal(proposal: any) {
 function talerPay(msg: any): Promise<any> {
   return new Promise(async(resolve, reject) => {
     // current URL without fragment
-    let url = new URI(document.location.href).fragment("").href();
-    let res = await queryPayment(url);
+    const url = new URI(document.location.href).fragment("").href();
+    const res = await queryPayment(url);
     logVerbose && console.log("taler-pay: got response", res);
     if (res && res.payReq) {
       resolve(res);
       return;
     }
     if (msg.contract_url) {
-      let nonce = await generateNonce();
-      let proposal = await downloadContract(msg.contract_url, nonce);
-      if (proposal.data.nonce != nonce) {
+      const nonce = await generateNonce();
+      const proposal = await downloadContract(msg.contract_url, nonce);
+      if (proposal.data.nonce !== nonce) {
         console.error("stale contract");
         return;
       }
@@ -421,10 +429,10 @@ function talerPay(msg: any): Promise<any> {
 function talerPaymentFailed(H_contract: string) {
   return new Promise(async(resolve, reject) => {
     const walletMsg = {
-      type: "payment-failed",
       detail: {
-        contractHash: H_contract
+        contractHash: H_contract,
       },
+      type: "payment-failed",
     };
     chrome.runtime.sendMessage(walletMsg, (resp) => {
       resolve();
@@ -444,11 +452,11 @@ function talerPaymentSucceeded(msg: any) {
     }
     logVerbose && console.log("got taler-payment-succeeded");
     const walletMsg = {
-      type: "payment-succeeded",
       detail: {
-        merchantSig: msg.merchantSig,
         contractHash: msg.H_contract,
+        merchantSig: msg.merchantSig,
       },
+      type: "payment-succeeded",
     };
     chrome.runtime.sendMessage(walletMsg, (resp) => {
       resolve();
@@ -463,21 +471,21 @@ function registerHandlers() {
    * handles adding sequence numbers to responses.
    */
   function addHandler(type: string, handler: HandlerFn) {
-    let handlerWrap = (e: CustomEvent) => {
-      if (e.type != type) {
+    const handlerWrap = (e: CustomEvent) => {
+      if (e.type !== type) {
         throw Error(`invariant violated`);
       }
-      let callId: number|undefined = undefined;
-      if (e.detail && e.detail.callId != undefined) {
+      let callId: number|undefined;
+      if (e.detail && e.detail.callId !== undefined) {
         callId = e.detail.callId;
       }
-      let responder = (msg?: any) => {
-        let fullMsg = Object.assign({}, msg, {callId});
+      const responder = (msg?: any) => {
+        const fullMsg = Object.assign({}, msg, {callId});
         let opts = { detail: fullMsg };
-        if ("function" == typeof cloneInto) {
+        if ("function" === typeof cloneInto) {
           opts = cloneInto(opts, document.defaultView);
         }
-        let evt = new CustomEvent(type + "-result", opts);
+        const evt = new CustomEvent(type + "-result", opts);
         document.dispatchEvent(evt);
       };
       handler(e.detail, responder);
@@ -489,7 +497,7 @@ function registerHandlers() {
 
   addHandler("taler-query-id", (msg: any, sendResponse: any) => {
     // FIXME: maybe include this info in taoer-probe?
-    sendResponse({id: chrome.runtime.id})
+    sendResponse({id: chrome.runtime.id});
   });
 
   addHandler("taler-probe", (msg: any, sendResponse: any) => {
@@ -497,34 +505,33 @@ function registerHandlers() {
   });
 
   addHandler("taler-create-reserve", (msg: any) => {
-    let params = {
+    const params = {
       amount: JSON.stringify(msg.amount),
-      callback_url: new URI(msg.callback_url)
-        .absoluteTo(document.location.href),
       bank_url: document.location.href,
-      wt_types: JSON.stringify(msg.wt_types),
+      callback_url: new URI(msg.callback_url) 
.absoluteTo(document.location.href),
       suggested_exchange_url: msg.suggested_exchange_url,
+      wt_types: JSON.stringify(msg.wt_types),
     };
-    let uri = new 
URI(chrome.extension.getURL("/src/pages/confirm-create-reserve.html"));
-    let redirectUrl = uri.query(params).href();
+    const uri = new 
URI(chrome.extension.getURL("/src/pages/confirm-create-reserve.html"));
+    const redirectUrl = uri.query(params).href();
     window.location.href = redirectUrl;
   });
 
   addHandler("taler-add-auditor", (msg: any) => {
-    let params = {
+    const params = {
       req: JSON.stringify(msg),
     };
-    let uri = new URI(chrome.extension.getURL("/src/pages/add-auditor.html"));
-    let redirectUrl = uri.query(params).href();
+    const uri = new 
URI(chrome.extension.getURL("/src/pages/add-auditor.html"));
+    const redirectUrl = uri.query(params).href();
     window.location.href = redirectUrl;
   });
 
   addHandler("taler-confirm-reserve", (msg: any, sendResponse: any) => {
-    let walletMsg = {
-      type: "confirm-reserve",
+    const walletMsg = {
       detail: {
-        reservePub: msg.reserve_pub
-      }
+        reservePub: msg.reserve_pub,
+      },
+      type: "confirm-reserve",
     };
     chrome.runtime.sendMessage(walletMsg, (resp) => {
       sendResponse();
@@ -544,7 +551,7 @@ function registerHandlers() {
   });
 
   addHandler("taler-pay", async(msg: any, sendResponse: any) => {
-    let resp = await talerPay(msg);
+    const resp = await talerPay(msg);
     sendResponse(resp);
   });
 
diff --git a/src/crypto/cryptoApi-test.ts b/src/crypto/cryptoApi-test.ts
index cc5d1156..60bd44c9 100644
--- a/src/crypto/cryptoApi-test.ts
+++ b/src/crypto/cryptoApi-test.ts
@@ -1,80 +1,104 @@
-import {CryptoApi} from "./cryptoApi";
-import {ReserveRecord, DenominationRecord, DenominationStatus} from "../types";
+/*
+ This file is part of TALER
+ (C) 2017 Inria and GNUnet e.V.
+
+ 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/>
+ */
+
+// tslint:disable:max-line-length
+
 import {test} from "ava";
 
-let masterPub1: string = 
"CQQZ9DY3MZ1ARMN5K1VKDETS04Y2QCKMMCFHZSWJWWVN82BTTH00";
+import {
+  DenominationRecord,
+  DenominationStatus,
+  ReserveRecord,
+} from "../types";
 
-let denomValid1: DenominationRecord = {
-  masterSig: 
"CJFJCQ48Q45PSGJ5KY94N6M2TPARESM2E15BSPBD95YVVPEARAEQ6V6G4Z2XBMS0QM0F3Y9EYVP276FCS90EQ1578ZC8JHFBZ3NGP3G",
-  stampStart: "/Date(1473148381)/",
-  stampExpireWithdraw: "/Date(2482300381)/",
-  stampExpireDeposit: "/Date(1851580381)/",
+import {CryptoApi} from "./cryptoApi";
+
+const masterPub1: string = 
"CQQZ9DY3MZ1ARMN5K1VKDETS04Y2QCKMMCFHZSWJWWVN82BTTH00";
+
+const denomValid1: DenominationRecord = {
   denomPub: 
"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GHS84R3JHHP6GSM2D9Q6514CGT568R32C9J6CWM4DSH64TM4DSM851K0CA48CVKAC1P6H144C2160T46DHK8CVM4HJ274S38C1M6S338D9N6GWM8DT684T3JCT36S13EC9G88R3EGHQ8S0KJGSQ60SKGD216N33AGJ2651K2E9S60TMCD1N75244HHQ6X33EDJ570R3GGJ2651MACA38D130DA560VK4HHJ68WK2CA26GW3ECSH6D13EC9S88VK2GT66WVK8D9G750K0D9R8RRK4DHQ71332GHK8D23GE26710M2H9K6WVK8HJ38MVKEGA66N23AC9H88VKACT58MV3CCSJ6H1K4DT38GRK0C9M8N33CE1R60V4AHA38H1KECSH6S33JH9N8GRKGH1K68S36GH354520818CMG26C1H60R30C9
 [...]
-  stampExpireLegal: "/Date(1567756381)/",
-  value: {
-    "currency": "PUDOS",
-    "value": 0,
-    "fraction": 100000
-  },
-  feeWithdraw: {
-    "currency": "PUDOS",
-    "value": 0,
-    "fraction": 10000
-  },
+  denomPubHash: "dummy",
+  exchangeBaseUrl: "https://exchange.example.com/";,
   feeDeposit: {
-    "currency": "PUDOS",
-    "value": 0,
-    "fraction": 10000
+    currency: "PUDOS",
+    fraction: 10000,
+    value: 0,
   },
   feeRefresh: {
-    "currency": "PUDOS",
-    "value": 0,
-    "fraction": 10000
+    currency: "PUDOS",
+    fraction: 10000,
+    value: 0,
   },
   feeRefund: {
-    "currency": "PUDOS",
-    "value": 0,
-    "fraction": 10000
+    currency: "PUDOS",
+    fraction: 10000,
+    value: 0,
+  },
+  feeWithdraw: {
+    currency: "PUDOS",
+    fraction: 10000,
+    value: 0,
   },
-  denomPubHash: "dummy",
-  status: DenominationStatus.Unverified,
   isOffered: true,
-  exchangeBaseUrl: "https://exchange.example.com/";,
+  masterSig: 
"CJFJCQ48Q45PSGJ5KY94N6M2TPARESM2E15BSPBD95YVVPEARAEQ6V6G4Z2XBMS0QM0F3Y9EYVP276FCS90EQ1578ZC8JHFBZ3NGP3G",
+  stampExpireDeposit: "/Date(1851580381)/",
+  stampExpireLegal: "/Date(1567756381)/",
+  stampExpireWithdraw: "/Date(2482300381)/",
+  stampStart: "/Date(1473148381)/",
+  status: DenominationStatus.Unverified,
+  value: {
+    currency: "PUDOS",
+    fraction: 100000,
+    value: 0,
+  },
 };
 
-let denomInvalid1 = JSON.parse(JSON.stringify(denomValid1));
+const denomInvalid1 = JSON.parse(JSON.stringify(denomValid1));
 denomInvalid1.value.value += 1;
 
-test("string hashing", async t => {
-  let crypto = new CryptoApi();
-  let s = await crypto.hashString("hello taler");
-  let sh = 
"8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR";
-  t.true(s == sh);
+test("string hashing", async (t) => {
+  const crypto = new CryptoApi();
+  const s = await crypto.hashString("hello taler");
+  const sh = 
"8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR";
+  t.true(s === sh);
   t.pass();
 });
 
-test("precoin creation", async t => {
-  let crypto = new CryptoApi();
-  let {priv, pub} = await crypto.createEddsaKeypair();
-  let r: ReserveRecord = {
-    reserve_pub: pub,
-    reserve_priv: priv,
-    hasPayback: false,
-    exchange_base_url: "https://example.com/exchange";,
+test("precoin creation", async (t) => {
+  const crypto = new CryptoApi();
+  const {priv, pub} = await crypto.createEddsaKeypair();
+  const r: ReserveRecord = {
+    confirmed: false,
     created: 0,
-    requested_amount: {currency: "PUDOS", value: 0, fraction: 0},
-    precoin_amount: {currency: "PUDOS", value: 0, fraction: 0},
     current_amount: null,
-    confirmed: false,
+    exchange_base_url: "https://example.com/exchange";,
+    hasPayback: false,
     last_query: null,
+    precoin_amount: {currency: "PUDOS", value: 0, fraction: 0},
+    requested_amount: {currency: "PUDOS", value: 0, fraction: 0},
+    reserve_priv: priv,
+    reserve_pub: pub,
   };
 
-  let precoin = await crypto.createPreCoin(denomValid1, r);
+  const precoin = await crypto.createPreCoin(denomValid1, r);
   t.pass();
 });
 
-test("denom validation", async t => {
-  let crypto = new CryptoApi();
+test("denom validation", async (t) => {
+  const crypto = new CryptoApi();
   let v: boolean;
   v = await crypto.isValidDenom(denomValid1, masterPub1);
   t.true(v);
diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts
index b291cd17..57f035a8 100644
--- a/src/crypto/cryptoApi.ts
+++ b/src/crypto/cryptoApi.ts
@@ -24,20 +24,22 @@
  * Imports.
  */
 import {
-  PreCoinRecord,
-  CoinRecord,
-  ReserveRecord,
   AmountJson,
+  CoinRecord,
   DenominationRecord,
+  PayCoinInfo,
   PaybackRequest,
+  PreCoinRecord,
   RefreshSessionRecord,
+  ReserveRecord,
   WireFee,
-  PayCoinInfo,
 } from "../types";
+
 import {
-  OfferRecord,
   CoinWithDenom,
+  OfferRecord,
 } from "../wallet";
+
 import * as timer from "../timer";
 
 import { startWorker } from "./startWorker";
@@ -76,8 +78,6 @@ interface WorkItem {
 }
 
 
-
-
 /**
  * Number of different priorities. Each priority p
  * must be 0 <= p < NUM_PRIO.
@@ -97,34 +97,35 @@ export class CryptoApi {
    * Start a worker (if not started) and set as busy.
    */
   wake<T>(ws: WorkerState, work: WorkItem): void {
-    if (ws.currentWorkItem != null) {
+    if (ws.currentWorkItem !== null) {
       throw Error("assertion failed");
     }
     ws.currentWorkItem = work;
     this.numBusy++;
     if (!ws.w) {
-      let w = startWorker();
+      const w = startWorker();
       w.onmessage = (m: MessageEvent) => this.handleWorkerMessage(ws, m);
       w.onerror = (e: ErrorEvent) => this.handleWorkerError(ws, e);
       ws.w = w;
     }
 
-    let msg: any = {
-      operation: work.operation, args: work.args,
-      id: work.rpcId
+    const msg: any = {
+      args: work.args,
+      id: work.rpcId,
+      operation: work.operation,
     };
     this.resetWorkerTimeout(ws);
     ws.w!.postMessage(msg);
   }
 
   resetWorkerTimeout(ws: WorkerState) {
-    if (ws.terminationTimerHandle != null) {
+    if (ws.terminationTimerHandle !== null) {
       ws.terminationTimerHandle.clear();
       ws.terminationTimerHandle = null;
     }
-    let destroy = () => {
+    const destroy = () => {
       // terminate worker if it's idle
-      if (ws.w && ws.currentWorkItem == null) {
+      if (ws.w && ws.currentWorkItem === null) {
         ws.w!.terminate();
         ws.w = null;
       }
@@ -146,7 +147,7 @@ export class CryptoApi {
     } catch (e) {
       console.error(e);
     }
-    if (ws.currentWorkItem != null) {
+    if (ws.currentWorkItem !== null) {
       ws.currentWorkItem.reject(e);
       ws.currentWorkItem = null;
       this.numBusy--;
@@ -157,9 +158,9 @@ export class CryptoApi {
   findWork(ws: WorkerState) {
     // try to find more work for this worker
     for (let i = 0; i < NUM_PRIO; i++) {
-      let q = this.workQueues[NUM_PRIO - i - 1];
-      if (q.length != 0) {
-        let work: WorkItem = q.shift()!;
+      const q = this.workQueues[NUM_PRIO - i - 1];
+      if (q.length !== 0) {
+        const work: WorkItem = q.shift()!;
         this.wake(ws, work);
         return;
       }
@@ -167,12 +168,12 @@ export class CryptoApi {
   }
 
   handleWorkerMessage(ws: WorkerState, msg: MessageEvent) {
-    let id = msg.data.id;
+    const id = msg.data.id;
     if (typeof id !== "number") {
       console.error("rpc id must be number");
       return;
     }
-    let currentWorkItem = ws.currentWorkItem;
+    const currentWorkItem = ws.currentWorkItem;
     ws.currentWorkItem = null;
     this.numBusy--;
     this.findWork(ws);
@@ -180,7 +181,7 @@ export class CryptoApi {
       console.error("unsolicited response from worker");
       return;
     }
-    if (id != currentWorkItem.rpcId) {
+    if (id !== currentWorkItem.rpcId) {
       console.error(`RPC with id ${id} has no registry entry`);
       return;
     }
@@ -191,6 +192,7 @@ export class CryptoApi {
     let concurrency = 2;
     try {
       // only works in the browser
+      // tslint:disable-next-line:no-string-literal
       concurrency = (navigator as any)["hardwareConcurrency"];
     } catch (e) {
       // ignore
@@ -199,9 +201,9 @@ export class CryptoApi {
 
     for (let i = 0; i < this.workers.length; i++) {
       this.workers[i] = {
-        w: null,
-        terminationTimerHandle: null,
         currentWorkItem: null,
+        terminationTimerHandle: null,
+        w: null,
       };
     }
     this.workQueues = [];
@@ -212,14 +214,14 @@ export class CryptoApi {
 
   private doRpc<T>(operation: string, priority: number,
                    ...args: any[]): Promise<T> {
-    let start = timer.performanceNow();
+    const start = timer.performanceNow();
 
-    let p = new Promise((resolve, reject) => {
-      let rpcId = this.nextRpcId++;
-      let workItem: WorkItem = {operation, args, resolve, reject, rpcId};
+    const p = new Promise((resolve, reject) => {
+      const rpcId = this.nextRpcId++;
+      const workItem: WorkItem = {operation, args, resolve, reject, rpcId};
 
-      if (this.numBusy == this.workers.length) {
-        let q = this.workQueues[priority];
+      if (this.numBusy === this.workers.length) {
+        const q = this.workQueues[priority];
         if (!q) {
           throw Error("assertion failed");
         }
@@ -227,9 +229,8 @@ export class CryptoApi {
         return;
       }
 
-      for (let i = 0; i < this.workers.length; i++) {
-        let ws = this.workers[i];
-        if (ws.currentWorkItem != null) {
+      for (const ws of this.workers) {
+        if (ws.currentWorkItem !== null) {
           continue;
         }
 
diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts
index 36b3b924..9541b744 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -37,12 +37,11 @@ import {
   ReserveRecord,
   WireFee,
 } from "../types";
-import create = chrome.alarms.create;
 import {
   CoinWithDenom,
   OfferRecord,
 } from "../wallet";
-import * as native from "./emscInterface";
+
 import {
   Amount,
   EddsaPublicKey,
@@ -50,6 +49,7 @@ import {
   HashContext,
   RefreshMeltCoinAffirmationPS,
 } from "./emscInterface";
+import * as native from "./emscInterface";
 
 
 namespace RpcFunctions {
@@ -60,18 +60,16 @@ namespace RpcFunctions {
    */
   export function createPreCoin(denom: DenominationRecord,
                                 reserve: ReserveRecord): PreCoinRecord {
-    let reservePriv = new native.EddsaPrivateKey();
+    const reservePriv = new native.EddsaPrivateKey();
     reservePriv.loadCrock(reserve.reserve_priv);
-    let reservePub = new native.EddsaPublicKey();
+    const reservePub = new native.EddsaPublicKey();
     reservePub.loadCrock(reserve.reserve_pub);
-    let denomPub = native.RsaPublicKey.fromCrock(denom.denomPub);
-    let coinPriv = native.EddsaPrivateKey.create();
-    let coinPub = coinPriv.getPublicKey();
-    let blindingFactor = native.RsaBlindingKeySecret.create();
-    let pubHash: native.HashCode = coinPub.hash();
-    let ev = native.rsaBlind(pubHash,
-                             blindingFactor,
-                             denomPub);
+    const denomPub = native.RsaPublicKey.fromCrock(denom.denomPub);
+    const coinPriv = native.EddsaPrivateKey.create();
+    const coinPub = coinPriv.getPublicKey();
+    const blindingFactor = native.RsaBlindingKeySecret.create();
+    const pubHash: native.HashCode = coinPub.hash();
+    const ev = native.rsaBlind(pubHash, blindingFactor, denomPub);
 
     if (!ev) {
       throw Error("couldn't blind (malicious exchange key?)");
@@ -81,61 +79,61 @@ namespace RpcFunctions {
       throw Error("Field fee_withdraw missing");
     }
 
-    let amountWithFee = new native.Amount(denom.value);
+    const amountWithFee = new native.Amount(denom.value);
     amountWithFee.add(new native.Amount(denom.feeWithdraw));
-    let withdrawFee = new native.Amount(denom.feeWithdraw);
+    const withdrawFee = new native.Amount(denom.feeWithdraw);
 
     // Signature
-    let withdrawRequest = new native.WithdrawRequestPS({
-      reserve_pub: reservePub,
+    const withdrawRequest = new native.WithdrawRequestPS({
       amount_with_fee: amountWithFee.toNbo(),
-      withdraw_fee: withdrawFee.toNbo(),
+      h_coin_envelope: ev.hash(),
       h_denomination_pub: denomPub.encode().hash(),
-      h_coin_envelope: ev.hash()
+      reserve_pub: reservePub,
+      withdraw_fee: withdrawFee.toNbo(),
     });
 
-    var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
+    const sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
 
-    let preCoin: PreCoinRecord = {
-      reservePub: reservePub.toCrock(),
+    const preCoin: PreCoinRecord = {
       blindingKey: blindingFactor.toCrock(),
-      coinPub: coinPub.toCrock(),
+      coinEv: ev.toCrock(),
       coinPriv: coinPriv.toCrock(),
+      coinPub: coinPub.toCrock(),
+      coinValue: denom.value,
       denomPub: denomPub.encode().toCrock(),
       exchangeBaseUrl: reserve.exchange_base_url,
+      reservePub: reservePub.toCrock(),
       withdrawSig: sig.toCrock(),
-      coinEv: ev.toCrock(),
-      coinValue: denom.value
     };
     return preCoin;
   }
 
   export function createPaybackRequest(coin: CoinRecord): PaybackRequest {
-    let p = new native.PaybackRequestPS({
+    const p = new native.PaybackRequestPS({
+      coin_blind: native.RsaBlindingKeySecret.fromCrock(coin.blindingKey),
       coin_pub: native.EddsaPublicKey.fromCrock(coin.coinPub),
       h_denom_pub: 
native.RsaPublicKey.fromCrock(coin.denomPub).encode().hash(),
-      coin_blind: native.RsaBlindingKeySecret.fromCrock(coin.blindingKey),
     });
-    let coinPriv = native.EddsaPrivateKey.fromCrock(coin.coinPriv);
-    let coinSig = native.eddsaSign(p.toPurpose(), coinPriv);
-    let paybackRequest: PaybackRequest = {
-      denom_pub: coin.denomPub,
-      denom_sig: coin.denomSig,
+    const coinPriv = native.EddsaPrivateKey.fromCrock(coin.coinPriv);
+    const coinSig = native.eddsaSign(p.toPurpose(), coinPriv);
+    const paybackRequest: PaybackRequest = {
       coin_blind_key_secret: coin.blindingKey,
       coin_pub: coin.coinPub,
       coin_sig: coinSig.toCrock(),
+      denom_pub: coin.denomPub,
+      denom_sig: coin.denomSig,
     };
     return paybackRequest;
   }
 
 
   export function isValidPaymentSignature(sig: string, contractHash: string, 
merchantPub: string): boolean {
-    let p = new native.PaymentSignaturePS({
+    const p = new native.PaymentSignaturePS({
       contract_hash: native.HashCode.fromCrock(contractHash),
     });
-    let nativeSig = new native.EddsaSignature();
+    const nativeSig = new native.EddsaSignature();
     nativeSig.loadCrock(sig);
-    let nativePub = native.EddsaPublicKey.fromCrock(merchantPub);
+    const nativePub = native.EddsaPublicKey.fromCrock(merchantPub);
     return native.eddsaVerify(native.SignaturePurpose.MERCHANT_PAYMENT_OK,
                               p.toPurpose(),
                               nativeSig,
@@ -143,17 +141,17 @@ namespace RpcFunctions {
   }
 
   export function isValidWireFee(type: string, wf: WireFee, masterPub: 
string): boolean {
-    let p = new native.MasterWireFeePS({
+    const p = new native.MasterWireFeePS({
+      closing_fee: (new native.Amount(wf.closingFee)).toNbo(),
+      end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp),
       h_wire_method: native.ByteArray.fromStringWithNull(type).hash(),
       start_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.startStamp),
-      end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp),
       wire_fee: (new native.Amount(wf.wireFee)).toNbo(),
-      closing_fee: (new native.Amount(wf.closingFee)).toNbo(),
     });
 
-    let nativeSig = new native.EddsaSignature();
+    const nativeSig = new native.EddsaSignature();
     nativeSig.loadCrock(wf.sig);
-    let nativePub = native.EddsaPublicKey.fromCrock(masterPub);
+    const nativePub = native.EddsaPublicKey.fromCrock(masterPub);
 
     return native.eddsaVerify(native.SignaturePurpose.MASTER_WIRE_FEES,
                               p.toPurpose(),
@@ -164,26 +162,24 @@ namespace RpcFunctions {
 
   export function isValidDenom(denom: DenominationRecord,
                                masterPub: string): boolean {
-    let p = new native.DenominationKeyValidityPS({
-      master: native.EddsaPublicKey.fromCrock(masterPub),
-      denom_hash: native.RsaPublicKey.fromCrock(denom.denomPub)
-                        .encode()
-                        .hash(),
+    const p = new native.DenominationKeyValidityPS({
+      denom_hash: native.RsaPublicKey.fromCrock(denom.denomPub) .encode() 
.hash(),
       expire_legal: 
native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireLegal),
       expire_spend: 
native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireDeposit),
       expire_withdraw: 
native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireWithdraw),
-      start: native.AbsoluteTimeNbo.fromTalerString(denom.stampStart),
-      value: (new native.Amount(denom.value)).toNbo(),
       fee_deposit: (new native.Amount(denom.feeDeposit)).toNbo(),
       fee_refresh: (new native.Amount(denom.feeRefresh)).toNbo(),
-      fee_withdraw: (new native.Amount(denom.feeWithdraw)).toNbo(),
       fee_refund: (new native.Amount(denom.feeRefund)).toNbo(),
+      fee_withdraw: (new native.Amount(denom.feeWithdraw)).toNbo(),
+      master: native.EddsaPublicKey.fromCrock(masterPub),
+      start: native.AbsoluteTimeNbo.fromTalerString(denom.stampStart),
+      value: (new native.Amount(denom.value)).toNbo(),
     });
 
-    let nativeSig = new native.EddsaSignature();
+    const nativeSig = new native.EddsaSignature();
     nativeSig.loadCrock(denom.masterSig);
 
-    let nativePub = native.EddsaPublicKey.fromCrock(masterPub);
+    const nativePub = native.EddsaPublicKey.fromCrock(masterPub);
 
     return 
native.eddsaVerify(native.SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY,
                               p.toPurpose(),
@@ -201,10 +197,10 @@ namespace RpcFunctions {
 
 
   export function rsaUnblind(sig: string, bk: string, pk: string): string {
-    let denomSig = native.rsaUnblind(native.RsaSignature.fromCrock(sig),
+    const denomSig = native.rsaUnblind(native.RsaSignature.fromCrock(sig),
                                      native.RsaBlindingKeySecret.fromCrock(bk),
                                      native.RsaPublicKey.fromCrock(pk));
-    return denomSig.encode().toCrock()
+    return denomSig.encode().toCrock();
   }
 
 
@@ -214,21 +210,21 @@ namespace RpcFunctions {
    */
   export function signDeposit(offer: OfferRecord,
                               cds: CoinWithDenom[]): PayCoinInfo {
-    let ret: PayCoinInfo = [];
+    const ret: PayCoinInfo = [];
 
 
-    let feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit);
+    const feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit);
     let fees = Amounts.add(Amounts.getZero(feeList[0].currency), 
...feeList).amount;
     // okay if saturates
     fees = Amounts.sub(fees, offer.contract.max_fee).amount;
-    let total = Amounts.add(fees, offer.contract.amount).amount;
+    const total = Amounts.add(fees, offer.contract.amount).amount;
 
-    let amountSpent = 
native.Amount.getZero(cds[0].coin.currentAmount.currency);
-    let amountRemaining = new native.Amount(total);
-    for (let cd of cds) {
+    const amountSpent = 
native.Amount.getZero(cds[0].coin.currentAmount.currency);
+    const amountRemaining = new native.Amount(total);
+    for (const cd of cds) {
       let coinSpend: Amount;
 
-      if (amountRemaining.value == 0 && amountRemaining.fraction == 0) {
+      if (amountRemaining.value === 0 && amountRemaining.fraction === 0) {
         break;
       }
 
@@ -241,7 +237,7 @@ namespace RpcFunctions {
       amountSpent.add(coinSpend);
       amountRemaining.sub(coinSpend);
 
-      let feeDeposit: Amount = new native.Amount(cd.denom.feeDeposit);
+      const feeDeposit: Amount = new native.Amount(cd.denom.feeDeposit);
 
       // Give the merchant at least the deposit fee, otherwise it'll reject
       // the coin.
@@ -249,32 +245,32 @@ namespace RpcFunctions {
         coinSpend = feeDeposit;
       }
 
-      let newAmount = new native.Amount(cd.coin.currentAmount);
+      const newAmount = new native.Amount(cd.coin.currentAmount);
       newAmount.sub(coinSpend);
       cd.coin.currentAmount = newAmount.toJson();
       cd.coin.status = CoinStatus.TransactionPending;
 
-      let d = new native.DepositRequestPS({
-        h_contract: native.HashCode.fromCrock(offer.H_contract),
-        h_wire: native.HashCode.fromCrock(offer.contract.H_wire),
+      const d = new native.DepositRequestPS({
         amount_with_fee: coinSpend.toNbo(),
         coin_pub: native.EddsaPublicKey.fromCrock(cd.coin.coinPub),
         deposit_fee: new native.Amount(cd.denom.feeDeposit).toNbo(),
+        h_contract: native.HashCode.fromCrock(offer.H_contract),
+        h_wire: native.HashCode.fromCrock(offer.contract.H_wire),
         merchant: native.EddsaPublicKey.fromCrock(offer.contract.merchant_pub),
         refund_deadline: 
native.AbsoluteTimeNbo.fromTalerString(offer.contract.refund_deadline),
         timestamp: 
native.AbsoluteTimeNbo.fromTalerString(offer.contract.timestamp),
       });
 
-      let coinSig = native.eddsaSign(d.toPurpose(),
+      const coinSig = native.eddsaSign(d.toPurpose(),
                                      
native.EddsaPrivateKey.fromCrock(cd.coin.coinPriv))
                           .toCrock();
 
-      let s: CoinPaySig = {
-        coin_sig: coinSig,
+      const s: CoinPaySig = {
         coin_pub: cd.coin.coinPub,
-        ub_sig: cd.coin.denomSig,
+        coin_sig: coinSig,
         denom_pub: cd.coin.denomPub,
         f: coinSpend.toJson(),
+        ub_sig: cd.coin.denomSig,
       };
       ret.push({sig: s, updatedCoin: cd.coin});
     }
@@ -290,7 +286,7 @@ namespace RpcFunctions {
 
     let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency);
 
-    for (let ncd of newCoinDenoms) {
+    for (const ncd of newCoinDenoms) {
       valueWithFee = Amounts.add(valueWithFee,
                                  ncd.value,
                                  ncd.feeWithdraw).amount;
@@ -299,23 +295,23 @@ namespace RpcFunctions {
     // melt fee
     valueWithFee = Amounts.add(valueWithFee, meltFee).amount;
 
-    let sessionHc = new HashContext();
+    const sessionHc = new HashContext();
 
-    let transferPubs: string[] = [];
-    let transferPrivs: string[] = [];
+    const transferPubs: string[] = [];
+    const transferPrivs: string[] = [];
 
-    let preCoinsForGammas: RefreshPreCoinRecord[][] = [];
+    const preCoinsForGammas: RefreshPreCoinRecord[][] = [];
 
     for (let i = 0; i < kappa; i++) {
-      let t = native.EcdhePrivateKey.create();
-      let pub = t.getPublicKey();
+      const t = native.EcdhePrivateKey.create();
+      const pub = t.getPublicKey();
       sessionHc.read(pub);
       transferPrivs.push(t.toCrock());
       transferPubs.push(pub.toCrock());
     }
 
-    for (let i = 0; i < newCoinDenoms.length; i++) {
-      let r = native.RsaPublicKey.fromCrock(newCoinDenoms[i].denomPub);
+    for (const denom of newCoinDenoms) {
+      const r = native.RsaPublicKey.fromCrock(denom.denomPub);
       sessionHc.read(r.encode());
     }
 
@@ -323,31 +319,31 @@ namespace RpcFunctions {
     sessionHc.read((new native.Amount(valueWithFee)).toNbo());
 
     for (let i = 0; i < kappa; i++) {
-      let preCoins: RefreshPreCoinRecord[] = [];
+      const preCoins: RefreshPreCoinRecord[] = [];
       for (let j = 0; j < newCoinDenoms.length; j++) {
 
-        let transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]);
-        let oldCoinPub = native.EddsaPublicKey.fromCrock(meltCoin.coinPub);
-        let transferSecret = native.ecdhEddsa(transferPriv, oldCoinPub);
+        const transferPriv = 
native.EcdhePrivateKey.fromCrock(transferPrivs[i]);
+        const oldCoinPub = native.EddsaPublicKey.fromCrock(meltCoin.coinPub);
+        const transferSecret = native.ecdhEddsa(transferPriv, oldCoinPub);
 
-        let fresh = native.setupFreshCoin(transferSecret, j);
+        const fresh = native.setupFreshCoin(transferSecret, j);
 
-        let coinPriv = fresh.priv;
-        let coinPub = coinPriv.getPublicKey();
-        let blindingFactor = fresh.blindingKey;
-        let pubHash: native.HashCode = coinPub.hash();
-        let denomPub = 
native.RsaPublicKey.fromCrock(newCoinDenoms[j].denomPub);
-        let ev = native.rsaBlind(pubHash,
+        const coinPriv = fresh.priv;
+        const coinPub = coinPriv.getPublicKey();
+        const blindingFactor = fresh.blindingKey;
+        const pubHash: native.HashCode = coinPub.hash();
+        const denomPub = 
native.RsaPublicKey.fromCrock(newCoinDenoms[j].denomPub);
+        const ev = native.rsaBlind(pubHash,
                                  blindingFactor,
                                  denomPub);
         if (!ev) {
           throw Error("couldn't blind (malicious exchange key?)");
         }
-        let preCoin: RefreshPreCoinRecord = {
+        const preCoin: RefreshPreCoinRecord = {
           blindingKey: blindingFactor.toCrock(),
           coinEv: ev.toCrock(),
-          publicKey: coinPub.toCrock(),
           privateKey: coinPriv.toCrock(),
+          publicKey: coinPub.toCrock(),
         };
         preCoins.push(preCoin);
         sessionHc.read(ev);
@@ -355,40 +351,40 @@ namespace RpcFunctions {
       preCoinsForGammas.push(preCoins);
     }
 
-    let sessionHash = new HashCode();
+    const sessionHash = new HashCode();
     sessionHash.alloc();
     sessionHc.finish(sessionHash);
 
-    let confirmData = new RefreshMeltCoinAffirmationPS({
-      coin_pub: EddsaPublicKey.fromCrock(meltCoin.coinPub),
+    const confirmData = new RefreshMeltCoinAffirmationPS({
       amount_with_fee: (new Amount(valueWithFee)).toNbo(),
+      coin_pub: EddsaPublicKey.fromCrock(meltCoin.coinPub),
+      melt_fee: (new Amount(meltFee)).toNbo(),
       session_hash: sessionHash,
-      melt_fee: (new Amount(meltFee)).toNbo()
     });
 
 
-    let confirmSig: string = native.eddsaSign(confirmData.toPurpose(),
+    const confirmSig: string = native.eddsaSign(confirmData.toPurpose(),
                                               native.EddsaPrivateKey.fromCrock(
                                                 meltCoin.coinPriv)).toCrock();
 
     let valueOutput = Amounts.getZero(newCoinDenoms[0].value.currency);
-    for (let denom of newCoinDenoms) {
+    for (const denom of newCoinDenoms) {
       valueOutput = Amounts.add(valueOutput, denom.value).amount;
     }
 
-    let refreshSession: RefreshSessionRecord = {
-      meltCoinPub: meltCoin.coinPub,
-      newDenoms: newCoinDenoms.map((d) => d.denomPub),
+    const refreshSession: RefreshSessionRecord = {
       confirmSig,
-      valueWithFee,
-      transferPubs,
-      preCoinsForGammas,
+      exchangeBaseUrl,
+      finished: false,
       hash: sessionHash.toCrock(),
+      meltCoinPub: meltCoin.coinPub,
+      newDenoms: newCoinDenoms.map((d) => d.denomPub),
       norevealIndex: undefined,
-      exchangeBaseUrl,
+      preCoinsForGammas,
       transferPrivs,
-      finished: false,
+      transferPubs,
       valueOutput,
+      valueWithFee,
     };
 
     return refreshSession;
@@ -408,24 +404,24 @@ namespace RpcFunctions {
 }
 
 
-let worker: Worker = (self as any) as Worker;
+const worker: Worker = (self as any) as Worker;
 
 worker.onmessage = (msg: MessageEvent) => {
   if (!Array.isArray(msg.data.args)) {
     console.error("args must be array");
     return;
   }
-  if (typeof msg.data.id != "number") {
+  if (typeof msg.data.id !== "number") {
     console.error("RPC id must be number");
   }
-  if (typeof msg.data.operation != "string") {
+  if (typeof msg.data.operation !== "string") {
     console.error("RPC operation must be string");
   }
-  let f = (RpcFunctions as any)[msg.data.operation];
+  const f = (RpcFunctions as any)[msg.data.operation];
   if (!f) {
     console.error(`unknown operation: '${msg.data.operation}'`);
     return;
   }
-  let res = f(...msg.data.args);
+  const res = f(...msg.data.args);
   worker.postMessage({result: res, id: msg.data.id});
-}
+};
diff --git a/src/crypto/emscInterface-test.ts b/src/crypto/emscInterface-test.ts
index dc98308f..789ac250 100644
--- a/src/crypto/emscInterface-test.ts
+++ b/src/crypto/emscInterface-test.ts
@@ -1,101 +1,124 @@
+/*
+ This file is part of TALER
+ (C) 2017 Inria and GNUnet e.V.
+
+ 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/>
+ */
+
+// tslint:disable:max-line-length
+
 import {test} from "ava";
 import * as native from "./emscInterface";
 
-test("string hashing", t => {
-  let x = native.ByteArray.fromStringWithNull("hello taler");
-  let h = 
"8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR"
-  let hc = x.hash().toCrock();
+test("string hashing", (t) => {
+  const x = native.ByteArray.fromStringWithNull("hello taler");
+  const h = 
"8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR";
+  const hc = x.hash().toCrock();
   console.log(`# hc ${hc}`);
   t.true(h === hc, "must equal");
   t.pass();
 });
 
-test("signing", t => {
-  let x = native.ByteArray.fromStringWithNull("hello taler");
-  let priv = native.EddsaPrivateKey.create();
-  let pub = priv.getPublicKey();
-  let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, 
x);
-  let sig = native.eddsaSign(purpose, priv);
+
+test("signing", (t) => {
+  const x = native.ByteArray.fromStringWithNull("hello taler");
+  const priv = native.EddsaPrivateKey.create();
+  const pub = priv.getPublicKey();
+  const purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, 
x);
+  const sig = native.eddsaSign(purpose, priv);
   t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
   t.pass();
 });
 
-test("signing-fixed-data", t => {
-  let x = native.ByteArray.fromStringWithNull("hello taler");
-  let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, 
x);
+
+test("signing-fixed-data", (t) => {
+  const x = native.ByteArray.fromStringWithNull("hello taler");
+  const purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, 
x);
   const privStr = "G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90";
   const pubStr = "YHCZB442FQFJ0ET20MWA8YJ53M61EZGJ6QKV1KTJZMRNXDY45WT0";
   const sigStr = 
"7V6XY4QGC1406GPMT305MZQ1HDCR7R0S5BP02GTGDQFPSXB6YD2YDN5ZS7NJQCNP61Y39MRHXNXQ1Z15JY4CJY4CPDA6CKQ3313WG38";
-  let priv = native.EddsaPrivateKey.fromCrock(privStr);
-  t.true(privStr == priv.toCrock())
-  let pub = priv.getPublicKey();
-  t.true(pubStr == pub.toCrock());
-  let sig = native.EddsaSignature.fromCrock(sigStr);
-  t.true(sigStr == sig.toCrock())
-  let sig2 = native.eddsaSign(purpose, priv);
-  t.true(sig.toCrock() == sig2.toCrock());
+  const priv = native.EddsaPrivateKey.fromCrock(privStr);
+  t.true(privStr === priv.toCrock());
+  const pub = priv.getPublicKey();
+  t.true(pubStr === pub.toCrock());
+  const sig = native.EddsaSignature.fromCrock(sigStr);
+  t.true(sigStr === sig.toCrock());
+  const sig2 = native.eddsaSign(purpose, priv);
+  t.true(sig.toCrock() === sig2.toCrock());
   t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
   t.pass();
 });
 
+
 const denomPubStr1 = 
"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30G9R64VK6HHS6MW42DSN8MVKJGHK6WR3CGT18MWMCDSM75138E1K8S0MADSQ68W34DHH6MW4CHA270W4CG9J6GW48DHG8MVK4E9S7523GEA56H0K4E1Q891KCCSG752KGC1M88VMCDSQ6D23CHHG8H33AGHG6MSK8GT26CRKAC1M64V3JCJ56CVKCC228MWMCHA26MS30H1J8MVKEDHJ70TMADHK892KJC1H60TKJDHM710KGGT584T38H9K851KCDHG60W30HJ28CT4CC1G8CR3JGJ28H236DJ28H330H9S890M2D9S8S14AGA369344GA36S248CHS70RKEDSS6MWKGDJ26D136GT465348CSS8S232CHM6GS34C9N8CS3GD9H60W36H1R8MSK2GSQ8MSM6C9R70SKCHHN6MW3AC
 [...]
 
-test("rsa-encode", t => {
-  const pubHashStr = 
"JM63YM5X7X547164QJ3MGJZ4WDD47GEQR5DW5SH35G4JFZXEJBHE5JBNZM5K8XN5C4BRW25BE6GSVAYBF790G2BZZ13VW91D41S4DS0"
-  let denomPub = native.RsaPublicKey.fromCrock(denomPubStr1);
-  let pubHash = denomPub.encode().hash();
-  t.true(pubHashStr == pubHash.toCrock());
+
+test("rsa-encode", (t) => {
+  const pubHashStr = 
"JM63YM5X7X547164QJ3MGJZ4WDD47GEQR5DW5SH35G4JFZXEJBHE5JBNZM5K8XN5C4BRW25BE6GSVAYBF790G2BZZ13VW91D41S4DS0";
+  const denomPub = native.RsaPublicKey.fromCrock(denomPubStr1);
+  const pubHash = denomPub.encode().hash();
+  t.true(pubHashStr === pubHash.toCrock());
   t.pass();
 });
 
 
-test("withdraw-request", t => {
+test("withdraw-request", (t) => {
   const reservePrivStr = 
"G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90";
   const reservePriv = native.EddsaPrivateKey.fromCrock(reservePrivStr);
   const reservePub = reservePriv.getPublicKey();
   const amountWithFee = new native.Amount({currency: "KUDOS", value: 1, 
fraction: 10000});
   amountWithFee.add(new native.Amount({currency: "KUDOS", value: 0, fraction: 
20000}));
-  const withdrawFee = new native.Amount({currency: "KUDOS", value: 0, 
fraction: 20000})
+  const withdrawFee = new native.Amount({currency: "KUDOS", value: 0, 
fraction: 20000});
   const denomPub = native.RsaPublicKey.fromCrock(denomPubStr1);
   const ev = native.ByteArray.fromStringWithNull("hello, world");
 
-
   // Signature
-  let withdrawRequest = new native.WithdrawRequestPS({
-    reserve_pub: reservePub,
+  const withdrawRequest = new native.WithdrawRequestPS({
     amount_with_fee: amountWithFee.toNbo(),
-    withdraw_fee: withdrawFee.toNbo(),
+    h_coin_envelope: ev.hash(),
     h_denomination_pub: denomPub.encode().hash(),
-    h_coin_envelope: ev.hash()
+    reserve_pub: reservePub,
+    withdraw_fee: withdrawFee.toNbo(),
   });
 
-  var sigStr = 
"AD3T8W44NV193J19RAN3NAJHPP6RVB0R3NWV7ZK5G8Q946YDK0B6F8YJBNRRBXSPVTKY31S7BVZPJFFTJJRMY61DH51X4JSXK677428";
+  const sigStr = 
"AD3T8W44NV193J19RAN3NAJHPP6RVB0R3NWV7ZK5G8Q946YDK0B6F8YJBNRRBXSPVTKY31S7BVZPJFFTJJRMY61DH51X4JSXK677428";
 
-  var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
+  const sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
   t.true(native.eddsaVerify(native.SignaturePurpose.RESERVE_WITHDRAW, 
withdrawRequest.toPurpose(), sig, reservePub));
-  t.true(sig.toCrock() == sigStr);
+  t.true(sig.toCrock() === sigStr);
   t.pass();
 });
 
-test("withdraw-request", t => {
+
+test("withdraw-request", (t) => {
   const a1 = new native.Amount({currency: "KUDOS", value: 1, fraction: 
50000000});
   const a2 = new native.Amount({currency: "KUDOS", value: 1, fraction: 
50000000});
   a1.add(a2);
-  let x = a1.toJson();
-  t.true(x.currency == "KUDOS");
-  t.true(x.fraction == 0);
-  t.true(x.value == 3);
+  const x = a1.toJson();
+  t.true(x.currency === "KUDOS");
+  t.true(x.fraction === 0);
+  t.true(x.value === 3);
   t.pass();
 });
 
 
-test("ecdsa", t => {
+test("ecdsa", (t) => {
   const priv = native.EcdsaPrivateKey.create();
   const pub1 = priv.getPublicKey();
   t.pass();
 });
 
-test("ecdhe", t => {
+
+test("ecdhe", (t) => {
   const priv = native.EcdhePrivateKey.create();
   const pub = priv.getPublicKey();
   t.pass();
diff --git a/src/crypto/emscInterface.ts b/src/crypto/emscInterface.ts
index 52c6c965..e00e67a8 100644
--- a/src/crypto/emscInterface.ts
+++ b/src/crypto/emscInterface.ts
@@ -27,8 +27,8 @@
  * Imports.
  */
 import {AmountJson} from "../types";
-import {getLib, EmscFunGen} from "./emscLoader";
 
+import {EmscFunGen, getLib} from "./emscLoader";
 
 const emscLib = getLib();
 
@@ -51,7 +51,7 @@ const GNUNET_SYSERR = -1;
 const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => {
   return (...args: any[]) => {
     return emscLib.ccall(name, ret, argTypes, args);
-  }
+  };
 };
 
 
@@ -59,84 +59,32 @@ const getEmsc: EmscFunGen = (name: string, ret: any, 
argTypes: any[]) => {
  * Wrapped emscripten functions that do not allocate any memory.
  */
 const emsc = {
+  amount_add: getEmsc("TALER_amount_add", "number", ["number", "number", 
"number"]),
+  amount_cmp: getEmsc("TALER_amount_cmp", "number", ["number", "number"]),
+  amount_get_zero: getEmsc("TALER_amount_get_zero", "number", ["string", 
"number"]),
+  amount_hton: getEmsc("TALER_amount_hton", "void", ["number", "number"]),
+  amount_normalize: getEmsc("TALER_amount_normalize", "void", ["number"]),
+  amount_ntoh: getEmsc("TALER_amount_ntoh", "void", ["number", "number"]),
+  amount_subtract: getEmsc("TALER_amount_subtract", "number", ["number", 
"number", "number"]),
+  ecdh_eddsa: getEmsc("GNUNET_CRYPTO_ecdh_eddsa", "number", ["number", 
"number", "number"]),
+  eddsa_sign: getEmsc("GNUNET_CRYPTO_eddsa_sign", "number", ["number", 
"number", "number"]),
+  eddsa_verify: getEmsc("GNUNET_CRYPTO_eddsa_verify", "number", ["number", 
"number", "number", "number"]),
   free: (ptr: number) => emscLib._free(ptr),
-  get_value: getEmsc("TALER_WR_get_value",
-                     "number",
-                     ["number"]),
-  get_fraction: getEmsc("TALER_WR_get_fraction",
-                        "number",
-                        ["number"]),
-  get_currency: getEmsc("TALER_WR_get_currency",
-                        "string",
-                        ["number"]),
-  amount_add: getEmsc("TALER_amount_add",
-                      "number",
-                      ["number", "number", "number"]),
-  amount_subtract: getEmsc("TALER_amount_subtract",
-                           "number",
-                           ["number", "number", "number"]),
-  amount_normalize: getEmsc("TALER_amount_normalize",
-                            "void",
-                            ["number"]),
-  amount_get_zero: getEmsc("TALER_amount_get_zero",
-                           "number",
-                           ["string", "number"]),
-  amount_cmp: getEmsc("TALER_amount_cmp",
-                      "number",
-                      ["number", "number"]),
-  amount_hton: getEmsc("TALER_amount_hton",
-                       "void",
-                       ["number", "number"]),
-  amount_ntoh: getEmsc("TALER_amount_ntoh",
-                       "void",
-                       ["number", "number"]),
-  hash: getEmsc("GNUNET_CRYPTO_hash",
-                "void",
-                ["number", "number", "number"]),
-  memmove: getEmsc("memmove",
-                   "number",
-                   ["number", "number", "number"]),
-  rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free",
-                               "void",
-                               ["number"]),
-  rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free",
-                              "void",
-                              ["number"]),
-  string_to_data: getEmsc("GNUNET_STRINGS_string_to_data",
-                          "number",
-                          ["number", "number", "number", "number"]),
-  eddsa_sign: getEmsc("GNUNET_CRYPTO_eddsa_sign",
-                      "number",
-                      ["number", "number", "number"]),
-  eddsa_verify: getEmsc("GNUNET_CRYPTO_eddsa_verify",
-                        "number",
-                        ["number", "number", "number", "number"]),
-  hash_create_random: getEmsc("GNUNET_CRYPTO_hash_create_random",
-                              "void",
-                              ["number", "number"]),
-  rsa_blinding_key_destroy: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free",
-                                    "void",
-                                    ["number"]),
-  random_block: getEmsc("GNUNET_CRYPTO_random_block",
-                        "void",
-                        ["number", "number", "number"]),
-  hash_context_abort: getEmsc("GNUNET_CRYPTO_hash_context_abort",
-                              "void",
-                              ["number"]),
-  hash_context_read: getEmsc("GNUNET_CRYPTO_hash_context_read",
-                             "void",
-                             ["number", "number", "number"]),
-  hash_context_finish: getEmsc("GNUNET_CRYPTO_hash_context_finish",
-                               "void",
-                               ["number", "number"]),
-  ecdh_eddsa: getEmsc("GNUNET_CRYPTO_ecdh_eddsa",
-                      "number",
-                     ["number", "number", "number"]),
-
-  setup_fresh_coin: getEmsc(
-    "TALER_setup_fresh_coin",
-    "void",
-    ["number", "number", "number"]),
+  get_currency: getEmsc("TALER_WR_get_currency", "string", ["number"]),
+  get_fraction: getEmsc("TALER_WR_get_fraction", "number", ["number"]),
+  get_value: getEmsc("TALER_WR_get_value", "number", ["number"]),
+  hash: getEmsc("GNUNET_CRYPTO_hash", "void", ["number", "number", "number"]),
+  hash_context_abort: getEmsc("GNUNET_CRYPTO_hash_context_abort", "void", 
["number"]),
+  hash_context_finish: getEmsc("GNUNET_CRYPTO_hash_context_finish", "void", 
["number", "number"]),
+  hash_context_read: getEmsc("GNUNET_CRYPTO_hash_context_read", "void", 
["number", "number", "number"]),
+  hash_create_random: getEmsc("GNUNET_CRYPTO_hash_create_random", "void", 
["number", "number"]),
+  memmove: getEmsc("memmove", "number", ["number", "number", "number"]),
+  random_block: getEmsc("GNUNET_CRYPTO_random_block", "void", ["number", 
"number", "number"]),
+  rsa_blinding_key_destroy: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free", 
"void", ["number"]),
+  rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free", "void", 
["number"]),
+  rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free", "void", 
["number"]),
+  setup_fresh_coin: getEmsc( "TALER_setup_fresh_coin", "void", ["number", 
"number", "number"]),
+  string_to_data: getEmsc("GNUNET_STRINGS_string_to_data", "number", 
["number", "number", "number", "number"]),
 };
 
 
@@ -144,64 +92,26 @@ const emsc = {
  * Emscripten functions that allocate memory.
  */
 const emscAlloc = {
-  get_amount: getEmsc("TALER_WRALL_get_amount",
-                      "number",
-                      ["number", "number", "number", "string"]),
-  eddsa_key_create: getEmsc("GNUNET_CRYPTO_eddsa_key_create",
-                            "number", []),
-  ecdsa_key_create: getEmsc("GNUNET_CRYPTO_ecdsa_key_create",
-                            "number", []),
-  ecdhe_key_create: getEmsc("GNUNET_CRYPTO_ecdhe_key_create",
-                            "number", []),
-  eddsa_public_key_from_private: getEmsc(
-    "TALER_WRALL_eddsa_public_key_from_private",
-    "number",
-    ["number"]),
-  ecdsa_public_key_from_private: getEmsc(
-    "TALER_WRALL_ecdsa_public_key_from_private",
-    "number",
-    ["number"]),
-  ecdhe_public_key_from_private: getEmsc(
-    "TALER_WRALL_ecdhe_public_key_from_private",
-    "number",
-    ["number"]),
-  data_to_string_alloc: getEmsc("GNUNET_STRINGS_data_to_string_alloc",
-                                "number",
-                                ["number", "number"]),
-  purpose_create: getEmsc("TALER_WRALL_purpose_create",
-                          "number",
-                          ["number", "number", "number"]),
-  rsa_blind: getEmsc("GNUNET_CRYPTO_rsa_blind",
-                     "number",
-                     ["number", "number", "number", "number", "number"]),
-  rsa_blinding_key_create: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_create",
-                                   "number",
-                                   ["number"]),
-  rsa_blinding_key_encode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_encode",
-                                   "number",
-                                   ["number", "number"]),
-  rsa_signature_encode: getEmsc("GNUNET_CRYPTO_rsa_signature_encode",
-                                "number",
-                                ["number", "number"]),
-  rsa_blinding_key_decode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_decode",
-                                   "number",
-                                   ["number", "number"]),
-  rsa_public_key_decode: getEmsc("GNUNET_CRYPTO_rsa_public_key_decode",
-                                 "number",
-                                 ["number", "number"]),
-  rsa_signature_decode: getEmsc("GNUNET_CRYPTO_rsa_signature_decode",
-                                "number",
-                                ["number", "number"]),
-  rsa_public_key_encode: getEmsc("GNUNET_CRYPTO_rsa_public_key_encode",
-                                 "number",
-                                 ["number", "number"]),
-  rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind",
-                       "number",
-                       ["number", "number", "number"]),
-  hash_context_start: getEmsc("GNUNET_CRYPTO_hash_context_start",
-                              "number",
-                              []),
+  data_to_string_alloc: getEmsc("GNUNET_STRINGS_data_to_string_alloc", 
"number", ["number", "number"]),
+  ecdhe_key_create: getEmsc("GNUNET_CRYPTO_ecdhe_key_create", "number", []),
+  ecdhe_public_key_from_private: getEmsc( 
"TALER_WRALL_ecdhe_public_key_from_private", "number", ["number"]),
+  ecdsa_key_create: getEmsc("GNUNET_CRYPTO_ecdsa_key_create", "number", []),
+  ecdsa_public_key_from_private: getEmsc( 
"TALER_WRALL_ecdsa_public_key_from_private", "number", ["number"]),
+  eddsa_key_create: getEmsc("GNUNET_CRYPTO_eddsa_key_create", "number", []),
+  eddsa_public_key_from_private: getEmsc( 
"TALER_WRALL_eddsa_public_key_from_private", "number", ["number"]),
+  get_amount: getEmsc("TALER_WRALL_get_amount", "number", ["number", "number", 
"number", "string"]),
+  hash_context_start: getEmsc("GNUNET_CRYPTO_hash_context_start", "number", 
[]),
   malloc: (size: number) => emscLib._malloc(size),
+  purpose_create: getEmsc("TALER_WRALL_purpose_create", "number", ["number", 
"number", "number"]),
+  rsa_blind: getEmsc("GNUNET_CRYPTO_rsa_blind", "number", ["number", "number", 
"number", "number", "number"]),
+  rsa_blinding_key_create: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_create", 
"number", ["number"]),
+  rsa_blinding_key_decode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_decode", 
"number", ["number", "number"]),
+  rsa_blinding_key_encode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_encode", 
"number", ["number", "number"]),
+  rsa_public_key_decode: getEmsc("GNUNET_CRYPTO_rsa_public_key_decode", 
"number", ["number", "number"]),
+  rsa_public_key_encode: getEmsc("GNUNET_CRYPTO_rsa_public_key_encode", 
"number", ["number", "number"]),
+  rsa_signature_decode: getEmsc("GNUNET_CRYPTO_rsa_signature_decode", 
"number", ["number", "number"]),
+  rsa_signature_encode: getEmsc("GNUNET_CRYPTO_rsa_signature_encode", 
"number", ["number", "number"]),
+  rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind", "number", ["number", 
"number", "number"]),
 };
 
 
@@ -226,7 +136,7 @@ export enum SignaturePurpose {
 export enum RandomQuality {
   WEAK = 0,
   STRONG = 1,
-  NONCE = 2
+  NONCE = 2,
 }
 
 
@@ -301,8 +211,8 @@ abstract class MallocArenaObject implements ArenaObject {
 
   constructor(arena?: Arena) {
     if (!arena) {
-      if (arenaStack.length == 0) {
-        throw Error("No arena available")
+      if (arenaStack.length === 0) {
+        throw Error("No arena available");
       }
       arena = arenaStack[arenaStack.length - 1];
     }
@@ -349,7 +259,7 @@ interface Arena {
  * Arena that must be manually destroyed.
  */
 class SimpleArena implements Arena {
-  heap: Array<ArenaObject>;
+  heap: ArenaObject[];
 
   constructor() {
     this.heap = [];
@@ -360,10 +270,10 @@ class SimpleArena implements Arena {
   }
 
   destroy() {
-    for (let obj of this.heap) {
+    for (const obj of this.heap) {
       obj.destroy();
     }
-    this.heap = []
+    this.heap = [];
   }
 }
 
@@ -396,7 +306,7 @@ class SyncArena extends SimpleArena {
   }
 }
 
-let arenaStack: Arena[] = [];
+const arenaStack: Arena[] = [];
 arenaStack.push(new SyncArena());
 
 
@@ -417,9 +327,9 @@ export class Amount extends MallocArenaObject {
   }
 
   static getZero(currency: string, a?: Arena): Amount {
-    let am = new Amount(undefined, a);
-    let r = emsc.amount_get_zero(currency, am.nativePtr);
-    if (r != GNUNET_OK) {
+    const am = new Amount(undefined, a);
+    const r = emsc.amount_get_zero(currency, am.nativePtr);
+    if (r !== GNUNET_OK) {
       throw Error("invalid currency");
     }
     return am;
@@ -427,7 +337,7 @@ export class Amount extends MallocArenaObject {
 
 
   toNbo(a?: Arena): AmountNbo {
-    let x = new AmountNbo(a);
+    const x = new AmountNbo(a);
     x.alloc();
     emsc.amount_hton(x.nativePtr, this.nativePtr);
     return x;
@@ -445,15 +355,15 @@ export class Amount extends MallocArenaObject {
     return emsc.get_fraction(this.nativePtr);
   }
 
-  get currency(): String {
+  get currency(): string {
     return emsc.get_currency(this.nativePtr);
   }
 
   toJson(): AmountJson {
     return {
-      value: emsc.get_value(this.nativePtr),
+      currency: emsc.get_currency(this.nativePtr),
       fraction: emsc.get_fraction(this.nativePtr),
-      currency: emsc.get_currency(this.nativePtr)
+      value: emsc.get_value(this.nativePtr),
     };
   }
 
@@ -461,7 +371,7 @@ export class Amount extends MallocArenaObject {
    * Add an amount to this amount.
    */
   add(a: Amount) {
-    let res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr);
+    const res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr);
     if (res < 1) {
       // Overflow
       return false;
@@ -474,8 +384,8 @@ export class Amount extends MallocArenaObject {
    */
   sub(a: Amount) {
     // this = this - a
-    let res = emsc.amount_subtract(this.nativePtr, this.nativePtr, 
a.nativePtr);
-    if (res == 0) {
+    const res = emsc.amount_subtract(this.nativePtr, this.nativePtr, 
a.nativePtr);
+    if (res === 0) {
       // Underflow
       return false;
     }
@@ -503,10 +413,10 @@ export class Amount extends MallocArenaObject {
  * Count the UTF-8 characters in a JavaScript string.
  */
 function countUtf8Bytes(str: string): number {
-  var s = str.length;
+  let s = str.length;
   // JavaScript strings are UTF-16 arrays
   for (let i = str.length - 1; i >= 0; i--) {
-    var code = str.charCodeAt(i);
+    const code = str.charCodeAt(i);
     if (code > 0x7f && code <= 0x7ff) {
       // We need an extra byte in utf-8 here
       s++;
@@ -540,8 +450,8 @@ abstract class PackedArenaObject extends MallocArenaObject {
   }
 
   toCrock(): string {
-    var d = emscAlloc.data_to_string_alloc(this.nativePtr, this.size());
-    var s = emscLib.Pointer_stringify(d);
+    const d = emscAlloc.data_to_string_alloc(this.nativePtr, this.size());
+    const s = emscLib.Pointer_stringify(d);
     emsc.free(d);
     return s;
   }
@@ -557,8 +467,8 @@ abstract class PackedArenaObject extends MallocArenaObject {
     this.alloc();
     // We need to get the javascript string
     // to the emscripten heap first.
-    let buf = ByteArray.fromStringWithNull(s);
-    let res = emsc.string_to_data(buf.nativePtr,
+    const buf = ByteArray.fromStringWithNull(s);
+    const res = emsc.string_to_data(buf.nativePtr,
                                   s.length,
                                   this.nativePtr,
                                   this.size());
@@ -576,20 +486,20 @@ abstract class PackedArenaObject extends 
MallocArenaObject {
   }
 
   hash(): HashCode {
-    var x = new HashCode();
+    const x = new HashCode();
     x.alloc();
     emsc.hash(this.nativePtr, this.size(), x.nativePtr);
     return x;
   }
 
   hexdump() {
-    let bytes: string[] = [];
+    const bytes: string[] = [];
     for (let i = 0; i < this.size(); i++) {
       let b = emscLib.getValue(this.nativePtr + i, "i8");
       b = (b + 256) % 256;
       bytes.push("0".concat(b.toString(16)).slice(-2));
     }
-    let lines: string[] = [];
+    const lines: string[] = [];
     for (let i = 0; i < bytes.length; i += 8) {
       lines.push(bytes.slice(i, i + 8).join(","));
     }
@@ -607,10 +517,10 @@ export class AmountNbo extends PackedArenaObject {
   }
 
   toJson(): any {
-    let a = new SimpleArena();
-    let am = new Amount(undefined, a);
+    const a = new SimpleArena();
+    const am = new Amount(undefined, a);
     am.fromNbo(this);
-    let json = am.toJson();
+    const json = am.toJson();
     a.destroy();
     return json;
   }
@@ -621,7 +531,7 @@ export class AmountNbo extends PackedArenaObject {
  * Create a packed arena object from the base32 crockford encoding.
  */
 function fromCrock<T extends PackedArenaObject>(s: string, ctor: Ctor<T>): T {
-  let x: T = new ctor();
+  const x: T = new ctor();
   x.alloc();
   x.loadCrock(s);
   return x;
@@ -632,9 +542,11 @@ function fromCrock<T extends PackedArenaObject>(s: string, 
ctor: Ctor<T>): T {
  * Create a packed arena object from the base32 crockford encoding for objects
  * that have a special decoding function.
  */
-function fromCrockDecoded<T extends MallocArenaObject>(s: string, ctor: 
Ctor<T>, decodeFn: (p: number, s: number) => number): T {
-  let obj = new ctor();
-  let buf = ByteArray.fromCrock(s);
+function fromCrockDecoded<T extends MallocArenaObject>(s: string,
+                                                       ctor: Ctor<T>,
+                                                       decodeFn: (p: number, 
s: number) => number): T {
+  const obj = new ctor();
+  const buf = ByteArray.fromCrock(s);
   obj.nativePtr = decodeFn(buf.nativePtr, buf.size());
   buf.destroy();
   return obj;
@@ -645,10 +557,10 @@ function fromCrockDecoded<T extends MallocArenaObject>(s: 
string, ctor: Ctor<T>,
  * Encode an object using a special encoding function.
  */
 function encode<T extends MallocArenaObject>(obj: T, encodeFn: any, arena?: 
Arena): ByteArray {
-  let ptr = emscAlloc.malloc(PTR_SIZE);
-  let len = encodeFn(obj.nativePtr, ptr);
-  let res = new ByteArray(len, undefined, arena);
-  res.nativePtr = emscLib.getValue(ptr, '*');
+  const ptr = emscAlloc.malloc(PTR_SIZE);
+  const len = encodeFn(obj.nativePtr, ptr);
+  const res = new ByteArray(len, undefined, arena);
+  res.nativePtr = emscLib.getValue(ptr, "*");
   emsc.free(ptr);
   return res;
 }
@@ -659,7 +571,7 @@ function encode<T extends MallocArenaObject>(obj: T, 
encodeFn: any, arena?: Aren
  */
 export class EddsaPrivateKey extends PackedArenaObject {
   static create(a?: Arena): EddsaPrivateKey {
-    let obj = new EddsaPrivateKey(a);
+    const obj = new EddsaPrivateKey(a);
     obj.nativePtr = emscAlloc.eddsa_key_create();
     return obj;
   }
@@ -669,7 +581,7 @@ export class EddsaPrivateKey extends PackedArenaObject {
   }
 
   getPublicKey(a?: Arena): EddsaPublicKey {
-    let obj = new EddsaPublicKey(a);
+    const obj = new EddsaPublicKey(a);
     obj.nativePtr = emscAlloc.eddsa_public_key_from_private(this.nativePtr);
     return obj;
   }
@@ -682,7 +594,7 @@ export class EddsaPrivateKey extends PackedArenaObject {
 
 export class EcdsaPrivateKey extends PackedArenaObject {
   static create(a?: Arena): EcdsaPrivateKey {
-    let obj = new EcdsaPrivateKey(a);
+    const obj = new EcdsaPrivateKey(a);
     obj.nativePtr = emscAlloc.ecdsa_key_create();
     return obj;
   }
@@ -692,7 +604,7 @@ export class EcdsaPrivateKey extends PackedArenaObject {
   }
 
   getPublicKey(a?: Arena): EcdsaPublicKey {
-    let obj = new EcdsaPublicKey(a);
+    const obj = new EcdsaPublicKey(a);
     obj.nativePtr = emscAlloc.ecdsa_public_key_from_private(this.nativePtr);
     return obj;
   }
@@ -705,7 +617,7 @@ export class EcdsaPrivateKey extends PackedArenaObject {
 
 export class EcdhePrivateKey extends PackedArenaObject {
   static create(a?: Arena): EcdhePrivateKey {
-    let obj = new EcdhePrivateKey(a);
+    const obj = new EcdhePrivateKey(a);
     obj.nativePtr = emscAlloc.ecdhe_key_create();
     return obj;
   }
@@ -715,7 +627,7 @@ export class EcdhePrivateKey extends PackedArenaObject {
   }
 
   getPublicKey(a?: Arena): EcdhePublicKey {
-    let obj = new EcdhePublicKey(a);
+    const obj = new EcdhePublicKey(a);
     obj.nativePtr = emscAlloc.ecdhe_public_key_from_private(this.nativePtr);
     return obj;
   }
@@ -730,7 +642,7 @@ export class EcdhePrivateKey extends PackedArenaObject {
  * Constructor for a given type.
  */
 interface Ctor<T> {
-  new(): T
+  new(): T;
 }
 
 
@@ -774,7 +686,7 @@ export class RsaBlindingKeySecret extends PackedArenaObject 
{
    * Create a random blinding key secret.
    */
   static create(a?: Arena): RsaBlindingKeySecret {
-    let o = new RsaBlindingKeySecret(a);
+    const o = new RsaBlindingKeySecret(a);
     o.alloc();
     o.randomize();
     return o;
@@ -821,16 +733,16 @@ export class ByteArray extends PackedArenaObject {
 
   static fromStringWithoutNull(s: string, a?: Arena): ByteArray {
     // UTF-8 bytes, including 0-terminator
-    let terminatedByteLength = countUtf8Bytes(s) + 1;
-    let hstr = emscAlloc.malloc(terminatedByteLength);
+    const terminatedByteLength = countUtf8Bytes(s) + 1;
+    const hstr = emscAlloc.malloc(terminatedByteLength);
     emscLib.stringToUTF8(s, hstr, terminatedByteLength);
     return new ByteArray(terminatedByteLength - 1, hstr, a);
   }
 
   static fromStringWithNull(s: string, a?: Arena): ByteArray {
     // UTF-8 bytes, including 0-terminator
-    let terminatedByteLength = countUtf8Bytes(s) + 1;
-    let hstr = emscAlloc.malloc(terminatedByteLength);
+    const terminatedByteLength = countUtf8Bytes(s) + 1;
+    const hstr = emscAlloc.malloc(terminatedByteLength);
     emscLib.stringToUTF8(s, hstr, terminatedByteLength);
     return new ByteArray(terminatedByteLength, hstr, a);
   }
@@ -838,14 +750,14 @@ export class ByteArray extends PackedArenaObject {
   static fromCrock(s: string, a?: Arena): ByteArray {
     // this one is a bit more complicated than the other fromCrock functions,
     // since we don't have a fixed size
-    let byteLength = countUtf8Bytes(s);
-    let hstr = emscAlloc.malloc(byteLength + 1);
+    const byteLength = countUtf8Bytes(s);
+    const hstr = emscAlloc.malloc(byteLength + 1);
     emscLib.stringToUTF8(s, hstr, byteLength + 1);
-    let decodedLen = Math.floor((byteLength * 5) / 8);
-    let ba = new ByteArray(decodedLen, undefined, a);
-    let res = emsc.string_to_data(hstr, byteLength, ba.nativePtr, decodedLen);
+    const decodedLen = Math.floor((byteLength * 5) / 8);
+    const ba = new ByteArray(decodedLen, undefined, a);
+    const res = emsc.string_to_data(hstr, byteLength, ba.nativePtr, 
decodedLen);
     emsc.free(hstr);
-    if (res != GNUNET_OK) {
+    if (res !== GNUNET_OK) {
       throw Error("decoding failed");
     }
     return ba;
@@ -877,60 +789,60 @@ export class EccSignaturePurpose extends 
PackedArenaObject {
 
 
 abstract class SignatureStruct {
-  abstract fieldTypes(): Array<any>;
+  abstract fieldTypes(): any[];
 
   abstract purpose(): SignaturePurpose;
 
   private members: any = {};
 
   constructor(x: { [name: string]: any }) {
-    for (let k in x) {
+    for (const k in x) {
       this.set(k, x[k]);
     }
   }
 
   toPurpose(a?: Arena): EccSignaturePurpose {
     let totalSize = 0;
-    for (let f of this.fieldTypes()) {
-      let name = f[0];
-      let member = this.members[name];
+    for (const f of this.fieldTypes()) {
+      const name = f[0];
+      const member = this.members[name];
       if (!member) {
         throw Error(`Member ${name} not set`);
       }
       totalSize += member.size();
     }
 
-    let buf = emscAlloc.malloc(totalSize);
+    const buf = emscAlloc.malloc(totalSize);
     let ptr = buf;
-    for (let f of this.fieldTypes()) {
-      let name = f[0];
-      let member = this.members[name];
-      let size = member.size();
+    for (const f of this.fieldTypes()) {
+      const name = f[0];
+      const member = this.members[name];
+      const size = member.size();
       emsc.memmove(ptr, member.nativePtr, size);
       ptr += size;
     }
-    let ba = new ByteArray(totalSize, buf, a);
+    const ba = new ByteArray(totalSize, buf, a);
     return new EccSignaturePurpose(this.purpose(), ba);
   }
 
 
   toJson() {
-    let res: any = {};
-    for (let f of this.fieldTypes()) {
-      let name = f[0];
-      let member = this.members[name];
+    const res: any = {};
+    for (const f of this.fieldTypes()) {
+      const name = f[0];
+      const member = this.members[name];
       if (!member) {
         throw Error(`Member ${name} not set`);
       }
       res[name] = member.toJson();
     }
-    res["purpose"] = this.purpose();
+    res.purpose = this.purpose();
     return res;
   }
 
   protected set(name: string, value: PackedArenaObject) {
-    let typemap: any = {};
-    for (let f of this.fieldTypes()) {
+    const typemap: any = {};
+    for (const f of this.fieldTypes()) {
       typemap[f[0]] = f[1];
     }
     if (!(name in typemap)) {
@@ -969,7 +881,7 @@ export class WithdrawRequestPS extends SignatureStruct {
       ["amount_with_fee", AmountNbo],
       ["withdraw_fee", AmountNbo],
       ["h_denomination_pub", HashCode],
-      ["h_coin_envelope", HashCode]
+      ["h_coin_envelope", HashCode],
     ];
   }
 }
@@ -1023,7 +935,7 @@ export class RefreshMeltCoinAffirmationPS extends 
SignatureStruct {
       ["session_hash", HashCode],
       ["amount_with_fee", AmountNbo],
       ["melt_fee", AmountNbo],
-      ["coin_pub", EddsaPublicKey]
+      ["coin_pub", EddsaPublicKey],
     ];
   }
 }
@@ -1060,21 +972,21 @@ export class MasterWireFeePS extends SignatureStruct {
 
 export class AbsoluteTimeNbo extends PackedArenaObject {
   static fromTalerString(s: string): AbsoluteTimeNbo {
-    let x = new AbsoluteTimeNbo();
+    const x = new AbsoluteTimeNbo();
     x.alloc();
-    let r = /Date\(([0-9]+)\)/;
-    let m = r.exec(s);
-    if (!m || m.length != 2) {
+    const r = /Date\(([0-9]+)\)/;
+    const m = r.exec(s);
+    if (!m || m.length !== 2) {
       throw Error();
     }
-    let n = parseInt(m[1]) * 1000000;
+    const n = parseInt(m[1], 10) * 1000000;
     // XXX: This only works up to 54 bit numbers.
     set64(x.nativePtr, n);
     return x;
   }
 
   static fromStampSeconds(stamp: number): AbsoluteTimeNbo {
-    let x = new AbsoluteTimeNbo();
+    const x = new AbsoluteTimeNbo();
     x.alloc();
     // XXX: This only works up to 54 bit numbers.
     set64(x.nativePtr, stamp * 1000000);
@@ -1107,7 +1019,7 @@ function set32(p: number, n: number) {
 
 export class UInt64 extends PackedArenaObject {
   static fromNumber(n: number): UInt64 {
-    let x = new UInt64();
+    const x = new UInt64();
     x.alloc();
     set64(x.nativePtr, n);
     return x;
@@ -1121,7 +1033,7 @@ export class UInt64 extends PackedArenaObject {
 
 export class UInt32 extends PackedArenaObject {
   static fromNumber(n: number): UInt64 {
-    let x = new UInt32();
+    const x = new UInt32();
     x.alloc();
     set32(x.nativePtr, n);
     return x;
@@ -1204,7 +1116,7 @@ export class DenominationKeyValidityPS extends 
SignatureStruct {
       ["fee_deposit", AmountNbo],
       ["fee_refresh", AmountNbo],
       ["fee_refund", AmountNbo],
-      ["denom_hash", HashCode]
+      ["denom_hash", HashCode],
     ];
   }
 }
@@ -1283,18 +1195,18 @@ export function rsaBlind(hashCode: HashCode,
                          blindingKey: RsaBlindingKeySecret,
                          pkey: RsaPublicKey,
                          arena?: Arena): ByteArray|null {
-  let buf_ptr_out = emscAlloc.malloc(PTR_SIZE);
-  let buf_size_out = emscAlloc.malloc(PTR_SIZE);
-  let res = emscAlloc.rsa_blind(hashCode.nativePtr,
+  const buf_ptr_out = emscAlloc.malloc(PTR_SIZE);
+  const buf_size_out = emscAlloc.malloc(PTR_SIZE);
+  const res = emscAlloc.rsa_blind(hashCode.nativePtr,
                                 blindingKey.nativePtr,
                                 pkey.nativePtr,
                                 buf_ptr_out,
                                 buf_size_out);
-  let buf_ptr = emscLib.getValue(buf_ptr_out, '*');
-  let buf_size = emscLib.getValue(buf_size_out, '*');
+  const buf_ptr = emscLib.getValue(buf_ptr_out, "*");
+  const buf_size = emscLib.getValue(buf_size_out, "*");
   emsc.free(buf_ptr_out);
   emsc.free(buf_size_out);
-  if (res != GNUNET_OK) {
+  if (res !== GNUNET_OK) {
     // malicious key
     return null;
   }
@@ -1308,9 +1220,9 @@ export function rsaBlind(hashCode: HashCode,
 export function eddsaSign(purpose: EccSignaturePurpose,
                           priv: EddsaPrivateKey,
                           a?: Arena): EddsaSignature {
-  let sig = new EddsaSignature(a);
+  const sig = new EddsaSignature(a);
   sig.alloc();
-  let res = emsc.eddsa_sign(priv.nativePtr, purpose.nativePtr, sig.nativePtr);
+  const res = emsc.eddsa_sign(priv.nativePtr, purpose.nativePtr, 
sig.nativePtr);
   if (res < 1) {
     throw Error("EdDSA signing failed");
   }
@@ -1326,7 +1238,7 @@ export function eddsaVerify(purposeNum: number,
                             sig: EddsaSignature,
                             pub: EddsaPublicKey,
                             a?: Arena): boolean {
-  let r = emsc.eddsa_verify(purposeNum,
+  const r = emsc.eddsa_verify(purposeNum,
                             verify.nativePtr,
                             sig.nativePtr,
                             pub.nativePtr);
@@ -1341,7 +1253,7 @@ export function rsaUnblind(sig: RsaSignature,
                            bk: RsaBlindingKeySecret,
                            pk: RsaPublicKey,
                            a?: Arena): RsaSignature {
-  let x = new RsaSignature(a);
+  const x = new RsaSignature(a);
   x.nativePtr = emscAlloc.rsa_unblind(sig.nativePtr,
                                       bk.nativePtr,
                                       pk.nativePtr);
@@ -1362,10 +1274,10 @@ export interface FreshCoin {
  */
 export function ecdhEddsa(priv: EcdhePrivateKey,
                           pub: EddsaPublicKey): HashCode {
-  let h = new HashCode();
+  const h = new HashCode();
   h.alloc();
-  let res = emsc.ecdh_eddsa(priv.nativePtr, pub.nativePtr, h.nativePtr);
-  if (res != GNUNET_OK) {
+  const res = emsc.ecdh_eddsa(priv.nativePtr, pub.nativePtr, h.nativePtr);
+  if (res !== GNUNET_OK) {
     throw Error("ecdh_eddsa failed");
   }
   return h;
@@ -1377,11 +1289,11 @@ export function ecdhEddsa(priv: EcdhePrivateKey,
  */
 export function setupFreshCoin(secretSeed: TransferSecretP,
                                coinIndex: number): FreshCoin {
-  let priv = new EddsaPrivateKey();
+  const priv = new EddsaPrivateKey();
   priv.isWeak = true;
-  let blindingKey = new RsaBlindingKeySecret();
+  const blindingKey = new RsaBlindingKeySecret();
   blindingKey.isWeak = true;
-  let buf = new ByteArray(priv.size() + blindingKey.size());
+  const buf = new ByteArray(priv.size() + blindingKey.size());
 
   emsc.setup_fresh_coin(secretSeed.nativePtr, coinIndex, buf.nativePtr);
 
diff --git a/src/crypto/emscLoader.d.ts b/src/crypto/emscLoader.d.ts
index e46ed7f1..aac4116b 100644
--- a/src/crypto/emscLoader.d.ts
+++ b/src/crypto/emscLoader.d.ts
@@ -20,25 +20,25 @@ declare function getLib(): EmscLib;
 export interface EmscFunGen {
   (name: string,
    ret: string,
-   args: string[]): ((...x: (number|string)[]) => any);
+   args: string[]): ((...x: Array<number|string>) => any);
   (name: string,
    ret: "number",
-   args: string[]): ((...x: (number|string)[]) => number);
+   args: string[]): ((...x: Array<number|string>) => number);
   (name: string,
    ret: "void",
-   args: string[]): ((...x: (number|string)[]) => void);
+   args: string[]): ((...x: Array<number|string>) => void);
   (name: string,
    ret: "string",
-   args: string[]): ((...x: (number|string)[]) => string);
+   args: string[]): ((...x: Array<number|string>) => string);
 }
 
 
 interface EmscLib {
   cwrap: EmscFunGen;
 
-  ccall(name: string, ret:"number"|"string", argTypes: any[], args: any[]): any
+  ccall(name: string, ret: "number"|"string", argTypes: any[], args: any[]): 
any;
 
-  stringToUTF8(s: string, addr: number, maxLength: number): void
+  stringToUTF8(s: string, addr: number, maxLength: number): void;
 
   _free(ptr: number): void;
 
diff --git a/src/crypto/nodeWorker.ts b/src/crypto/nodeWorker.ts
index afa2930a..4352b66c 100644
--- a/src/crypto/nodeWorker.ts
+++ b/src/crypto/nodeWorker.ts
@@ -14,6 +14,9 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+
+// tslint:disable:no-var-requires
+
 const path = require("path");
 const fork = require("child_process").fork;
 
@@ -49,7 +52,7 @@ export class Worker {
       }
     });
 
-    this.child.send({scriptFilename,cwd: process.cwd()});
+    this.child.send({scriptFilename, cwd: process.cwd()});
   }
 
   addEventListener(event: "message" | "error", fn: (x: any) => void): void {
diff --git a/src/crypto/nodeWorkerEntry.ts b/src/crypto/nodeWorkerEntry.ts
index aa6f5759..ff7f8766 100644
--- a/src/crypto/nodeWorkerEntry.ts
+++ b/src/crypto/nodeWorkerEntry.ts
@@ -15,6 +15,8 @@
  */
 
 
+// tslint:disable:no-var-requires
+
 const fs = require("fs");
 const vm = require("vm");
 
@@ -22,57 +24,53 @@ process.once("message", (obj: any) => {
   const g: any = global as any;
 
   (g as any).self = {
+    addEventListener: (event: "error" | "message", fn: (x: any) => void) => {
+      if (event === "error") {
+        g.onerror = fn;
+      } else if (event === "message") {
+        g.onmessage = fn;
+      }
+    },
     close: () => {
       process.exit(0);
     },
-    postMessage: (msg: any) => {
-      const str: string = JSON.stringify({data: msg});
+    onerror: (err: any) => {
+      const str: string = JSON.stringify({error: err.message, stack: 
err.stack});
       if (process.send) {
         process.send(str);
       }
     },
     onmessage: undefined,
-    onerror: (err: any) => {
-      const str: string = JSON.stringify({error: err.message, stack: 
err.stack});
+    postMessage: (msg: any) => {
+      const str: string = JSON.stringify({data: msg});
       if (process.send) {
         process.send(str);
       }
     },
-    addEventListener: (event: "error" | "message", fn: (x: any) => void) => {
-      if (event == "error") {
-        g.onerror = fn;
-      } else if (event == "message") {
-        g.onmessage = fn;
-      }
-    },
   };
 
   g.__dirname = obj.cwd;
   g.__filename = __filename;
-  //g.require = require;
-  //g.module = module;
-  //g.exports = module.exports;
-
   g.importScripts = (...files: string[]) => {
     if (files.length > 0) {
-      vm.createScript(files.map(file => fs.readFileSync(file, 
"utf8")).join("\n")).runInThisContext();
+      vm.createScript(files.map((file) => fs.readFileSync(file, 
"utf8")).join("\n")).runInThisContext();
     }
   };
 
-  Object.keys(g.self).forEach(key => {
+  Object.keys(g.self).forEach((key) => {
     g[key] = g.self[key];
   });
 
   process.on("message", (msg: any) => {
     try {
-      (g.onmessage || g.self.onmessage || (() => {}))(JSON.parse(msg));
+      (g.onmessage || g.self.onmessage || (() => undefined))(JSON.parse(msg));
     } catch (err) {
-      (g.onerror || g.self.onerror || (() => {}))(err);
+      (g.onerror || g.self.onerror || (() => undefined))(err);
     }
   });
 
   process.on("error", (err: any) => {
-    (g.onerror || g.self.onerror || (() => {}))(err);
+    (g.onerror || g.self.onerror || (() => undefined))(err);
   });
 
   require(obj.scriptFilename);
diff --git a/src/helpers-test.ts b/src/helpers-test.ts
index 4e9b994d..8ce3c8e2 100644
--- a/src/helpers-test.ts
+++ b/src/helpers-test.ts
@@ -1,8 +1,25 @@
+/*
+ This file is part of TALER
+ (C) 2017 Inria and GNUnet e.V.
+
+ 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/>
+ */
+
+
 import {test} from "ava";
 import * as helpers from "./helpers";
 
 
-test("URL canonicalization", t => {
+test("URL canonicalization", (t) => {
   // converts to relative, adds https
   t.is(
     "https://alice.example.com/exchange/";,
diff --git a/src/helpers.ts b/src/helpers.ts
index 5e3ef06d..e5eb4021 100644
--- a/src/helpers.ts
+++ b/src/helpers.ts
@@ -30,7 +30,7 @@ import URI = require("urijs");
  * settings such as significant digits or currency symbols.
  */
 export function amountToPretty(amount: AmountJson): string {
-  let x = amount.value + amount.fraction / Amounts.fractionalBase;
+  const x = amount.value + amount.fraction / Amounts.fractionalBase;
   return `${x} ${amount.currency}`;
 }
 
@@ -41,14 +41,14 @@ export function amountToPretty(amount: AmountJson): string {
  * See http://api.taler.net/wallet.html#general
  */
 export function canonicalizeBaseUrl(url: string) {
-  let x = new URI(url);
+  const x = new URI(url);
   if (!x.protocol()) {
     x.protocol("https");
   }
   x.path(x.path() + "/").normalizePath();
   x.fragment("");
   x.query();
-  return x.href()
+  return x.href();
 }
 
 
@@ -59,23 +59,23 @@ export function canonicalizeBaseUrl(url: string) {
 export function canonicalJson(obj: any): string {
   // Check for cycles, etc.
   JSON.stringify(obj);
-  if (typeof obj == "string" || typeof obj == "number" || obj === null) {
-    return JSON.stringify(obj)
+  if (typeof obj === "string" || typeof obj === "number" || obj === null) {
+    return JSON.stringify(obj);
   }
   if (Array.isArray(obj)) {
-    let objs: string[] = obj.map((e) => canonicalJson(e));
-    return `[${objs.join(',')}]`;
+    const objs: string[] = obj.map((e) => canonicalJson(e));
+    return `[${objs.join(",")}]`;
   }
-  let keys: string[] = [];
-  for (let key in obj) {
+  const keys: string[] = [];
+  for (const key in obj) {
     keys.push(key);
   }
   keys.sort();
   let s = "{";
   for (let i = 0; i < keys.length; i++) {
-    let key = keys[i];
+    const key = keys[i];
     s += JSON.stringify(key) + ":" + canonicalJson(obj[key]);
-    if (i != keys.length - 1) {
+    if (i !== keys.length - 1) {
       s += ",";
     }
   }
@@ -92,7 +92,7 @@ export function deepEquals(x: any, y: any): boolean {
     return false;
   }
 
-  var p = Object.keys(x);
+  const p = Object.keys(x);
   return Object.keys(y).every((i) => p.indexOf(i) !== -1) &&
     p.every((i) => deepEquals(x[i], y[i]));
 }
@@ -112,7 +112,7 @@ export function getTalerStampSec(stamp: string): number | 
null {
   if (!m) {
     return null;
   }
-  return parseInt(m[1]);
+  return parseInt(m[1], 10);
 }
 
 
@@ -121,7 +121,7 @@ export function getTalerStampSec(stamp: string): number | 
null {
  * Returns null if input is not in the right format.
  */
 export function getTalerStampDate(stamp: string): Date | null {
-  let sec = getTalerStampSec(stamp);
+  const sec = getTalerStampSec(stamp);
   if (sec == null) {
     return null;
   }
diff --git a/src/http.ts b/src/http.ts
index 965a44a9..895b1097 100644
--- a/src/http.ts
+++ b/src/http.ts
@@ -46,10 +46,10 @@ export interface HttpRequestLibrary {
  */
 export class BrowserHttpLib {
   private req(method: string,
-      url: string,
-      options?: any): Promise<HttpResponse> {
+              url: string,
+              options?: any): Promise<HttpResponse> {
     return new Promise<HttpResponse>((resolve, reject) => {
-      let myRequest = new XMLHttpRequest();
+      const myRequest = new XMLHttpRequest();
       myRequest.open(method, url);
       if (options && options.req) {
         myRequest.send(options.req);
@@ -57,10 +57,10 @@ export class BrowserHttpLib {
         myRequest.send();
       }
       myRequest.addEventListener("readystatechange", (e) => {
-        if (myRequest.readyState == XMLHttpRequest.DONE) {
-          let resp = {
+        if (myRequest.readyState === XMLHttpRequest.DONE) {
+          const resp = {
+            responseText: myRequest.responseText,
             status: myRequest.status,
-            responseText: myRequest.responseText
           };
           resolve(resp);
         }
diff --git a/src/logging.ts b/src/logging.ts
index d5d6debf..19dd2f76 100644
--- a/src/logging.ts
+++ b/src/logging.ts
@@ -20,7 +20,11 @@
  * @author Florian Dold
  */
 
-import {Store, QueryRoot, openPromise} from "./query";
+import {
+  QueryRoot,
+  Store,
+  openPromise,
+} from "./query";
 
 export type Level = "error" | "debug" | "info" | "warn";
 
@@ -41,83 +45,92 @@ function makeDebug() {
 }
 
 export async function log(msg: string, level: Level = "info"): Promise<void> {
-  let ci = getCallInfo(2);
+  const ci = getCallInfo(2);
   return record(level, msg, undefined, ci.file, ci.line, ci.column);
 }
 
 function getCallInfo(level: number) {
   // see https://github.com/v8/v8/wiki/Stack-Trace-API
-  let stack = Error().stack;
+  const stack = Error().stack;
   if (!stack) {
     return unknownFrame;
   }
-  let lines = stack.split("\n");
+  const lines = stack.split("\n");
   return parseStackLine(lines[level + 1]);
 }
 
 interface Frame {
-  file?: string;
-  method?: string;
   column?: number;
+  file?: string;
   line?: number;
+  method?: string;
 }
 
 const unknownFrame: Frame = {
+  column: 0,
   file: "(unknown)",
-  method: "(unknown)",
   line: 0,
-  column: 0
+  method: "(unknown)",
 };
 
 /**
  * Adapted from https://github.com/errwischt/stacktrace-parser.
  */
 function parseStackLine(stackLine: string): Frame {
+  // tslint:disable-next-line:max-line-length
   const chrome = /^\s*at (?:(?:(?:Anonymous function)?|((?:\[object 
object\])?\S+(?: \[as \S+\])?)) 
)?\(?((?:file|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
   const gecko = 
/^(?:\s*(address@hidden)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
   const node  = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) 
)?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
   let parts;
 
-  if ((parts = gecko.exec(stackLine))) {
-    let f: Frame = {
+  parts = gecko.exec(stackLine);
+  if (parts) {
+    const f: Frame = {
+        column: parts[5] ? +parts[5] : undefined,
         file: parts[3],
-        method: parts[1] || "(unknown)",
         line: +parts[4],
-        column: parts[5] ? +parts[5] : undefined,
+        method: parts[1] || "(unknown)",
     };
     return f;
-  } else if ((parts = chrome.exec(stackLine))) {
-    let f: Frame = {
+  }
+
+  parts = chrome.exec(stackLine);
+  if (parts) {
+    const f: Frame = {
+        column: parts[4] ? +parts[4] : undefined,
         file: parts[2],
-        method: parts[1] || "(unknown)",
         line: +parts[3],
-        column: parts[4] ? +parts[4] : undefined,
+        method: parts[1] || "(unknown)",
     };
     return f;
-  } else if ((parts = node.exec(stackLine))) {
-    let f: Frame = {
+  }
+
+  parts = node.exec(stackLine);
+  if (parts) {
+    const f: Frame = {
+        column: parts[4] ? +parts[4] : undefined,
         file: parts[2],
-        method: parts[1] || "(unknown)",
         line: +parts[3],
-        column: parts[4] ? +parts[4] : undefined,
+        method: parts[1] || "(unknown)",
     };
     return f;
   }
+
   return unknownFrame;
 }
 
 
-let db: IDBDatabase|undefined = undefined;
+let db: IDBDatabase|undefined;
 
 export interface LogEntry {
-  timestamp: number;
+  col?: number;
+  detail?: string;
+  id?: number;
   level: string;
+  line?: number;
   msg: string;
-  detail?: string;
   source?: string;
-  col?: number;
-  line?: number;
-  id?: number;
+  timestamp: number;
 }
 
 export async function getLogs(): Promise<LogEntry[]> {
@@ -140,7 +153,7 @@ export async function recordException(msg: string, e: any): 
Promise<void> {
   try {
     stack = e.stack;
     if (stack) {
-      let lines = stack.split("\n");
+      const lines = stack.split("\n");
       frame = parseStackLine(lines[1]);
     }
   } catch (e) {
@@ -152,7 +165,12 @@ export async function recordException(msg: string, e: 
any): Promise<void> {
   return record("error", e.toString(), stack, frame.file, frame.line, 
frame.column);
 }
 
-export async function record(level: Level, msg: string, detail?: string, 
source?: string, line?: number, col?: number): Promise<void> {
+export async function record(level: Level,
+                             msg: string,
+                             detail?: string,
+                             source?: string,
+                             line?: number,
+                             col?: number): Promise<void> {
   if (typeof indexedDB === "undefined") {
     return;
   }
@@ -160,7 +178,7 @@ export async function record(level: Level, msg: string, 
detail?: string, source?
   let myBarrier: any;
 
   if (barrier) {
-    let p = barrier.promise;
+    const p = barrier.promise;
     myBarrier = barrier = openPromise();
     await p;
   } else {
@@ -172,20 +190,20 @@ export async function record(level: Level, msg: string, 
detail?: string, source?
       db = await openLoggingDb();
     }
 
-    let count = await new QueryRoot(db).count(logsStore);
+    const count = await new QueryRoot(db).count(logsStore);
 
     if (count > 1000) {
       await new QueryRoot(db).deleteIf(logsStore, (e, i) => (i < 200));
     }
 
-    let entry: LogEntry = {
-      timestamp: new Date().getTime(),
+    const entry: LogEntry = {
+      col,
+      detail,
       level,
+      line,
       msg,
       source,
-      line,
-      col,
-      detail,
+      timestamp: new Date().getTime(),
     };
     await new QueryRoot(db).put(logsStore, entry);
   } finally {
@@ -207,15 +225,15 @@ export function openLoggingDb(): Promise<IDBDatabase> {
       resolve(req.result);
     };
     req.onupgradeneeded = (e) => {
-      const db = req.result;
-      if (e.oldVersion != 0) {
+      const resDb = req.result;
+      if (e.oldVersion !== 0) {
         try {
-          db.deleteObjectStore("logs");
+          resDb.deleteObjectStore("logs");
         } catch (e) {
           console.error(e);
         }
       }
-      db.createObjectStore("logs", {keyPath: "id", autoIncrement: true});
+      resDb.createObjectStore("logs", {keyPath: "id", autoIncrement: true});
     };
   });
 }
diff --git a/src/pages/show-db.ts b/src/pages/show-db.ts
index 95525368..d9595138 100644
--- a/src/pages/show-db.ts
+++ b/src/pages/show-db.ts
@@ -23,32 +23,32 @@
 
 function replacer(match: string, pIndent: string, pKey: string, pVal: string,
                   pEnd: string) {
-  var key = '<span class=json-key>';
-  var val = '<span class=json-value>';
-  var str = '<span class=json-string>';
-  var r = pIndent || '';
+  const key = "<span class=json-key>";
+  const val = "<span class=json-value>";
+  const str = "<span class=json-string>";
+  let r = pIndent || "";
   if (pKey) {
-    r = r + key + '"' + pKey.replace(/[": ]/g, '') + '":</span> ';
+    r = r + key + '"' + pKey.replace(/[": ]/g, "") + '":</span> ';
   }
   if (pVal) {
-    r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
+    r = r + (pVal[0] === '"' ? str : val) + pVal + "</span>";
   }
-  return r + (pEnd || '');
+  return r + (pEnd || "");
 }
 
 
 function prettyPrint(obj: any) {
-  var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
+  const jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
   return JSON.stringify(obj, null as any, 3)
-             .replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
-             .replace(/</g, '&lt;').replace(/>/g, '&gt;')
+             .replace(/&/g, "&amp;").replace(/\\"/g, "&quot;")
+             .replace(/</g, "&lt;").replace(/>/g, "&gt;")
              .replace(jsonLine, replacer);
 }
 
 
 document.addEventListener("DOMContentLoaded", () => {
-  chrome.runtime.sendMessage({type: 'dump-db'}, (resp) => {
-    const el = document.getElementById('dump');
+  chrome.runtime.sendMessage({type: "dump-db"}, (resp) => {
+    const el = document.getElementById("dump");
     if (!el) {
       throw Error();
     }
@@ -56,7 +56,7 @@ document.addEventListener("DOMContentLoaded", () => {
 
     document.getElementById("download")!.addEventListener("click", (evt) => {
       console.log("creating download");
-      let element = document.createElement("a");
+      const element = document.createElement("a");
       element.setAttribute("href", "data:text/plain;charset=utf-8," + 
encodeURIComponent(JSON.stringify(resp)));
       element.setAttribute("download", "wallet-dump.txt");
       element.style.display = "none";
@@ -67,9 +67,9 @@ document.addEventListener("DOMContentLoaded", () => {
   });
 
 
-  let fileInput = document.getElementById("fileInput")! as HTMLInputElement;
+  const fileInput = document.getElementById("fileInput")! as HTMLInputElement;
   fileInput.onchange = (evt) => {
-    if (!fileInput.files || fileInput.files.length != 1) {
+    if (!fileInput.files || fileInput.files.length !== 1) {
       alert("please select exactly one file to import");
       return;
     }
@@ -77,9 +77,9 @@ document.addEventListener("DOMContentLoaded", () => {
     const fr = new FileReader();
     fr.onload = (e: any) => {
       console.log("got file");
-      let dump = JSON.parse(e.target.result);
+      const dump = JSON.parse(e.target.result);
       console.log("parsed contents", dump);
-      chrome.runtime.sendMessage({ type: 'import-db', detail: { dump } }, 
(resp) => {
+      chrome.runtime.sendMessage({ type: "import-db", detail: { dump } }, 
(resp) => {
         alert("loaded");
       });
     };
diff --git a/src/query.ts b/src/query.ts
index c593f061..78b81037 100644
--- a/src/query.ts
+++ b/src/query.ts
@@ -21,42 +21,42 @@
  * @author Florian Dold
  */
 
-"use strict";
 
-
-export interface JoinResult<L,R> {
+/**
+ * Result of an inner join.
+ */
+export interface JoinResult<L, R> {
   left: L;
   right: R;
 }
 
-export interface JoinLeftResult<L,R> {
+/**
+ * Result of a left outer join.
+ */
+export interface JoinLeftResult<L, R> {
   left: L;
   right?: R;
 }
 
 
+/**
+ * Definition of an object store.
+ */
 export class Store<T> {
-  name: string;
-  validator?: (v: T) => T;
-  storeParams?: IDBObjectStoreParameters;
-
-  constructor(name: string, storeParams?: IDBObjectStoreParameters,
-              validator?: (v: T) => T) {
-    this.name = name;
-    this.validator = validator;
-    this.storeParams = storeParams;
+  constructor(public name: string,
+              public storeParams?: IDBObjectStoreParameters,
+              public validator?: (v: T) => T) {
   }
 }
 
-export class Index<S extends IDBValidKey,T> {
-  indexName: string;
+/**
+ * Definition of an index.
+ */
+export class Index<S extends IDBValidKey, T> {
   storeName: string;
-  keyPath: string | string[];
 
-  constructor(s: Store<T>, indexName: string, keyPath: string | string[]) {
+  constructor(s: Store<T>, public indexName: string, public keyPath: string | 
string[]) {
     this.storeName = s.name;
-    this.indexName = indexName;
-    this.keyPath = keyPath;
   }
 }
 
@@ -65,17 +65,58 @@ export class Index<S extends IDBValidKey,T> {
  * with indices.
  */
 export interface QueryStream<T> {
-  indexJoin<S,I extends IDBValidKey>(index: Index<I,S>,
-                                     keyFn: (obj: T) => I): 
QueryStream<JoinResult<T, S>>;
-  indexJoinLeft<S,I extends IDBValidKey>(index: Index<I,S>,
-                                     keyFn: (obj: T) => I): 
QueryStream<JoinLeftResult<T, S>>;
-  keyJoin<S,I extends IDBValidKey>(store: Store<S>,
-                                   keyFn: (obj: T) => I): 
QueryStream<JoinResult<T,S>>;
-  filter(f: (T: any) => boolean): QueryStream<T>;
+  /**
+   * Join the current query with values from an index.
+   * The left side of the join is extracted via a function from the stream's
+   * result, the right side of the join is the key of the index.
+   */
+  indexJoin<S, I extends IDBValidKey>(index: Index<I, S>, keyFn: (obj: T) => 
I): QueryStream<JoinResult<T, S>>;
+  /**
+   * Join the current query with values from an index, and keep values in the
+   * current stream that don't have a match.  The left side of the join is
+   * extracted via a function from the stream's result, the right side of the
+   * join is the key of the index.
+   */
+  indexJoinLeft<S, I extends IDBValidKey>(index: Index<I, S>,
+                                          keyFn: (obj: T) => I): 
QueryStream<JoinLeftResult<T, S>>;
+  /**
+   * Join the current query with values from another object store.
+   * The left side of the join is extracted via a function over the current 
query,
+   * the right side of the join is the key of the object store.
+   */
+  keyJoin<S, I extends IDBValidKey>(store: Store<S>, keyFn: (obj: T) => I): 
QueryStream<JoinResult<T, S>>;
+
+  /**
+   * Only keep elements in the result stream for which the predicate returns
+   * true.
+   */
+  filter(f: (x: T) => boolean): QueryStream<T>;
+
+  /**
+   * Reduce the stream, resulting in a single value.
+   */
   reduce<S>(f: (v: T, acc: S) => S, start?: S): Promise<S>;
-  map<S>(f: (x:T) => S): QueryStream<S>;
+
+  /**
+   * Map each element of the stream using a function, resulting in another
+   * stream of a different type.
+   */
+  map<S>(f: (x: T) => S): QueryStream<S>;
+
+  /**
+   * Map each element of the stream to a potentially empty array, and collect
+   * the result in a stream of the flattened arrays.
+   */
   flatMap<S>(f: (x: T) => S[]): QueryStream<S>;
+
+  /**
+   * Collect the stream into an array and return a promise for it.
+   */
   toArray(): Promise<T[]>;
+
+  /**
+   * Get the first value of the stream.
+   */
   first(): QueryValue<T>;
 
   then(onfulfill: any, onreject: any): any;
@@ -99,7 +140,7 @@ abstract class BaseQueryValue<T> implements QueryValue<T> {
   }
 
   map<S>(f: (x: T) => S): QueryValue<S> {
-    return new MapQueryValue<T,S>(this, f);
+    return new MapQueryValue<T, S>(this, f);
   }
 
   cond<R>(f: (x: T) => boolean, onTrue: (r: QueryRoot) => R, onFalse: (r: 
QueryRoot) => R): Promise<void> {
@@ -141,7 +182,7 @@ class FirstQueryValue<T> extends BaseQueryValue<T> {
   }
 }
 
-class MapQueryValue<T,S> extends BaseQueryValue<S> {
+class MapQueryValue<T, S> extends BaseQueryValue<S> {
   mapFn: (x: T) => S;
   v: BaseQueryValue<T>;
 
@@ -157,7 +198,10 @@ class MapQueryValue<T,S> extends BaseQueryValue<S> {
 }
 
 
-export let AbortTransaction = Symbol("abort_transaction");
+/**
+ * Exception that should be thrown by client code to abort a transaction.
+ */
+export const AbortTransaction = Symbol("abort_transaction");
 
 /**
  * Get an unresolved promise together with its extracted resolve / reject
@@ -193,26 +237,27 @@ abstract class QueryStreamBase<T> implements 
QueryStream<T>, PromiseLike<void> {
     return new FirstQueryValue(this);
   }
 
-  then<R>(onfulfilled: (value: void) => R | PromiseLike<R>, onrejected: 
(reason: any) => R | PromiseLike<R>): PromiseLike<R>  {
+  then<R>(onfulfilled: (value: void) => R | PromiseLike<R>,
+          onrejected: (reason: any) => R | PromiseLike<R>): PromiseLike<R>  {
     return this.root.then(onfulfilled, onrejected);
   }
 
   flatMap<S>(f: (x: T) => S[]): QueryStream<S> {
-    return new QueryStreamFlatMap<T,S>(this, f);
+    return new QueryStreamFlatMap<T, S>(this, f);
   }
 
   map<S>(f: (x: T) => S): QueryStream<S> {
     return new QueryStreamMap(this, f);
   }
 
-  indexJoin<S,I extends IDBValidKey>(index: Index<I,S>,
-                                     keyFn: (obj: T) => I): 
QueryStream<JoinResult<T, S>> {
+  indexJoin<S, I extends IDBValidKey>(index: Index<I, S>,
+                                      keyFn: (obj: T) => I): 
QueryStream<JoinResult<T, S>> {
     this.root.addStoreAccess(index.storeName, false);
     return new QueryStreamIndexJoin<T, S>(this, index.storeName, 
index.indexName, keyFn);
   }
 
-  indexJoinLeft<S,I extends IDBValidKey>(index: Index<I,S>,
-                                     keyFn: (obj: T) => I): 
QueryStream<JoinLeftResult<T, S>> {
+  indexJoinLeft<S, I extends IDBValidKey>(index: Index<I, S>,
+                                          keyFn: (obj: T) => I): 
QueryStream<JoinLeftResult<T, S>> {
     this.root.addStoreAccess(index.storeName, false);
     return new QueryStreamIndexJoinLeft<T, S>(this, index.storeName, 
index.indexName, keyFn);
   }
@@ -228,8 +273,8 @@ abstract class QueryStreamBase<T> implements 
QueryStream<T>, PromiseLike<void> {
   }
 
   toArray(): Promise<T[]> {
-    let {resolve, promise} = openPromise();
-    let values: T[] = [];
+    const {resolve, promise} = openPromise();
+    const values: T[] = [];
 
     this.subscribe((isDone, value) => {
       if (isDone) {
@@ -245,7 +290,7 @@ abstract class QueryStreamBase<T> implements 
QueryStream<T>, PromiseLike<void> {
   }
 
   reduce<A>(f: (x: any, acc?: A) => A, init?: A): Promise<any> {
-    let {resolve, promise} = openPromise();
+    const {resolve, promise} = openPromise();
     let acc = init;
 
     this.subscribe((isDone, value) => {
@@ -265,10 +310,7 @@ abstract class QueryStreamBase<T> implements 
QueryStream<T>, PromiseLike<void> {
 type FilterFn = (e: any) => boolean;
 type SubscribeFn = (done: boolean, value: any, tx: IDBTransaction) => void;
 type SubscribeOneFn = (value: any, tx: IDBTransaction) => void;
-
-interface FlatMapFn<T> {
-  (v: T): T[];
-}
+type FlatMapFn<T> = (v: T) => T[];
 
 class QueryStreamFilter<T> extends QueryStreamBase<T> {
   s: QueryStreamBase<T>;
@@ -294,7 +336,7 @@ class QueryStreamFilter<T> extends QueryStreamBase<T> {
 }
 
 
-class QueryStreamFlatMap<T,S> extends QueryStreamBase<S> {
+class QueryStreamFlatMap<T, S> extends QueryStreamBase<S> {
   s: QueryStreamBase<T>;
   flatMapFn: (v: T) => S[];
 
@@ -310,16 +352,16 @@ class QueryStreamFlatMap<T,S> extends QueryStreamBase<S> {
         f(true, undefined, tx);
         return;
       }
-      let values = this.flatMapFn(value);
-      for (let v in values) {
-        f(false, value, tx)
+      const values = this.flatMapFn(value);
+      for (const v in values) {
+        f(false, value, tx);
       }
     });
   }
 }
 
 
-class QueryStreamMap<S,T> extends QueryStreamBase<T> {
+class QueryStreamMap<S, T> extends QueryStreamBase<T> {
   s: QueryStreamBase<S>;
   mapFn: (v: S) => T;
 
@@ -335,7 +377,7 @@ class QueryStreamMap<S,T> extends QueryStreamBase<T> {
         f(true, undefined, tx);
         return;
       }
-      let mappedValue = this.mapFn(value);
+      const mappedValue = this.mapFn(value);
       f(false, mappedValue, tx);
     });
   }
@@ -363,15 +405,15 @@ class QueryStreamIndexJoin<T, S> extends 
QueryStreamBase<JoinResult<T, S>> {
         f(true, undefined, tx);
         return;
       }
-      let s = tx.objectStore(this.storeName).index(this.indexName);
-      let req = s.openCursor(IDBKeyRange.only(this.key(value)));
+      const s = tx.objectStore(this.storeName).index(this.indexName);
+      const req = s.openCursor(IDBKeyRange.only(this.key(value)));
       req.onsuccess = () => {
-        let cursor = req.result;
+        const cursor = req.result;
         if (cursor) {
           f(false, {left: value, right: cursor.value}, tx);
           cursor.continue();
         }
-      }
+      };
     });
   }
 }
@@ -402,7 +444,7 @@ class QueryStreamIndexJoinLeft<T, S> extends 
QueryStreamBase<JoinLeftResult<T, S
       const req = s.openCursor(IDBKeyRange.only(this.key(value)));
       let gotMatch = false;
       req.onsuccess = () => {
-        let cursor = req.result;
+        const cursor = req.result;
         if (cursor) {
           gotMatch = true;
           f(false, {left: value, right: cursor.value}, tx);
@@ -412,7 +454,7 @@ class QueryStreamIndexJoinLeft<T, S> extends 
QueryStreamBase<JoinLeftResult<T, S
             f(false, {left: value}, tx);
           }
         }
-      }
+      };
     });
   }
 }
@@ -437,17 +479,17 @@ class QueryStreamKeyJoin<T, S> extends 
QueryStreamBase<JoinResult<T, S>> {
         f(true, undefined, tx);
         return;
       }
-      let s = tx.objectStore(this.storeName);
-      let req = s.openCursor(IDBKeyRange.only(this.key(value)));
+      const s = tx.objectStore(this.storeName);
+      const req = s.openCursor(IDBKeyRange.only(this.key(value)));
       req.onsuccess = () => {
-        let cursor = req.result;
+        const cursor = req.result;
         if (cursor) {
-          f(false, {left:value, right: cursor.value}, tx);
+          f(false, {left: value, right: cursor.value}, tx);
           cursor.continue();
         } else {
           f(true, undefined, tx);
         }
-      }
+      };
     });
   }
 }
@@ -464,7 +506,7 @@ class IterQueryStream<T> extends QueryStreamBase<T> {
     this.storeName = storeName;
     this.subscribers = [];
 
-    let doIt = (tx: IDBTransaction) => {
+    const doIt = (tx: IDBTransaction) => {
       const {indexName = void 0, only = void 0} = this.options;
       let s: any;
       if (indexName !== void 0) {
@@ -473,24 +515,24 @@ class IterQueryStream<T> extends QueryStreamBase<T> {
       } else {
         s = tx.objectStore(this.storeName);
       }
-      let kr: IDBKeyRange | undefined = undefined;
+      let kr: IDBKeyRange | undefined;
       if (only !== undefined) {
         kr = IDBKeyRange.only(this.options.only);
       }
-      let req = s.openCursor(kr);
+      const req = s.openCursor(kr);
       req.onsuccess = () => {
-        let cursor: IDBCursorWithValue = req.result;
+        const cursor: IDBCursorWithValue = req.result;
         if (cursor) {
-          for (let f of this.subscribers) {
+          for (const f of this.subscribers) {
             f(false, cursor.value, tx);
           }
           cursor.continue();
         } else {
-          for (let f of this.subscribers) {
+          for (const f of this.subscribers) {
             f(true, undefined, tx);
           }
         }
-      }
+      };
     };
 
     this.root.addWork(doIt);
@@ -503,8 +545,7 @@ class IterQueryStream<T> extends QueryStreamBase<T> {
 
 
 export class QueryRoot implements PromiseLike<void> {
-  private work: ((t: IDBTransaction) => void)[] = [];
-  db: IDBDatabase;
+  private work: Array<((t: IDBTransaction) => void)> = [];
   private stores = new Set();
   private kickoffPromise: Promise<void>;
 
@@ -518,20 +559,23 @@ export class QueryRoot implements PromiseLike<void> {
 
   private finished: boolean = false;
 
-  constructor(db: IDBDatabase) {
-    this.db = db;
+  constructor(public db: IDBDatabase) {
   }
 
-  then<R>(onfulfilled: (value: void) => R | PromiseLike<R>, onrejected: 
(reason: any) => R | PromiseLike<R>): PromiseLike<R> {
+  then<R>(onfulfilled: (value: void) => R | PromiseLike<R>,
+          onrejected: (reason: any) => R | PromiseLike<R>): PromiseLike<R> {
     return this.finish().then(onfulfilled, onrejected);
   }
 
-  checkFinished() {
+  private checkFinished() {
     if (this.finished) {
       throw Error("Can't add work to query after it was started");
     }
   }
 
+  /**
+   * Get a stream of all objects in the store.
+   */
   iter<T>(store: Store<T>): QueryStream<T> {
     this.checkFinished();
     this.stores.add(store.name);
@@ -539,6 +583,9 @@ export class QueryRoot implements PromiseLike<void> {
     return new IterQueryStream<T>(this, store.name, {});
   }
 
+  /**
+   * Count the number of objects in a store.
+   */
   count<T>(store: Store<T>): Promise<number> {
     this.checkFinished();
     const {resolve, promise} = openPromise();
@@ -549,7 +596,7 @@ export class QueryRoot implements PromiseLike<void> {
       req.onsuccess = () => {
         resolve(req.result);
       };
-    }
+    };
 
     this.addWork(doCount, store.name, false);
     return Promise.resolve()
@@ -558,6 +605,9 @@ export class QueryRoot implements PromiseLike<void> {
 
   }
 
+  /**
+   * Delete all objects in a store that match a predicate.
+   */
   deleteIf<T>(store: Store<T>, predicate: (x: T, n: number) => boolean): 
QueryRoot {
     this.checkFinished();
     const doDeleteIf = (tx: IDBTransaction) => {
@@ -565,27 +615,27 @@ export class QueryRoot implements PromiseLike<void> {
       const req = s.openCursor();
       let n = 0;
       req.onsuccess = () => {
-        let cursor: IDBCursorWithValue = req.result;
+        const cursor: IDBCursorWithValue = req.result;
         if (cursor) {
           if (predicate(cursor.value, n++)) {
             cursor.delete();
           }
           cursor.continue();
-        } 
-      }
+        }
+      };
     };
     this.addWork(doDeleteIf, store.name, true);
     return this;
   }
 
-  iterIndex<S extends IDBValidKey,T>(index: Index<S,T>,
-                                     only?: S): QueryStream<T> {
+  iterIndex<S extends IDBValidKey, T>(index: Index<S, T>,
+                                      only?: S): QueryStream<T> {
     this.checkFinished();
     this.stores.add(index.storeName);
     this.scheduleFinish();
     return new IterQueryStream<T>(this, index.storeName, {
+      indexName: index.indexName,
       only,
-      indexName: index.indexName
     });
   }
 
@@ -596,7 +646,7 @@ export class QueryRoot implements PromiseLike<void> {
    */
   put<T>(store: Store<T>, val: T): QueryRoot {
     this.checkFinished();
-    let doPut = (tx: IDBTransaction) => {
+    const doPut = (tx: IDBTransaction) => {
       tx.objectStore(store.name).put(val);
     };
     this.scheduleFinish();
@@ -608,11 +658,11 @@ export class QueryRoot implements PromiseLike<void> {
   putWithResult<T>(store: Store<T>, val: T): Promise<IDBValidKey> {
     this.checkFinished();
     const {resolve, promise} = openPromise();
-    let doPutWithResult = (tx: IDBTransaction) => {
-      let req = tx.objectStore(store.name).put(val);
+    const doPutWithResult = (tx: IDBTransaction) => {
+      const req = tx.objectStore(store.name).put(val);
       req.onsuccess = () => {
         resolve(req.result);
-      }
+      };
       this.scheduleFinish();
     };
     this.addWork(doPutWithResult, store.name, true);
@@ -622,17 +672,20 @@ export class QueryRoot implements PromiseLike<void> {
   }
 
 
+  /**
+   * Get, modify and store an element inside a transaction.
+   */
   mutate<T>(store: Store<T>, key: any, f: (v: T) => T): QueryRoot {
     this.checkFinished();
-    let doPut = (tx: IDBTransaction) => {
-      let reqGet = tx.objectStore(store.name).get(key);
+    const doPut = (tx: IDBTransaction) => {
+      const reqGet = tx.objectStore(store.name).get(key);
       reqGet.onsuccess = () => {
-        let r = reqGet.result;
+        const r = reqGet.result;
         let m: T;
         try {
           m = f(r);
         } catch (e) {
-          if (e == AbortTransaction) {
+          if (e === AbortTransaction) {
             tx.abort();
             return;
           }
@@ -640,7 +693,7 @@ export class QueryRoot implements PromiseLike<void> {
         }
 
         tx.objectStore(store.name).put(m);
-      }
+      };
     };
     this.scheduleFinish();
     this.addWork(doPut, store.name, true);
@@ -656,7 +709,7 @@ export class QueryRoot implements PromiseLike<void> {
   putAll<T>(store: Store<T>, iterable: T[]): QueryRoot {
     this.checkFinished();
     const doPutAll = (tx: IDBTransaction) => {
-      for (let obj of iterable) {
+      for (const obj of iterable) {
         tx.objectStore(store.name).put(obj);
       }
     };
@@ -707,8 +760,8 @@ export class QueryRoot implements PromiseLike<void> {
   /**
    * Get one object from a store by its key.
    */
-  getIndexed<I extends IDBValidKey,T>(index: Index<I,T>,
-                                      key: I): Promise<T|undefined> {
+  getIndexed<I extends IDBValidKey, T>(index: Index<I, T>,
+                                       key: I): Promise<T|undefined> {
     this.checkFinished();
     if (key === void 0) {
       throw Error("key must not be undefined");
@@ -748,7 +801,7 @@ export class QueryRoot implements PromiseLike<void> {
     this.kickoffPromise = new Promise<void>((resolve, reject) => {
       // At this point, we can't add any more work
       this.finished = true;
-      if (this.work.length == 0) {
+      if (this.work.length === 0) {
         resolve();
         return;
       }
@@ -760,7 +813,7 @@ export class QueryRoot implements PromiseLike<void> {
       tx.onabort = () => {
         reject(Error("transaction aborted"));
       };
-      for (let w of this.work) {
+      for (const w of this.work) {
         w(tx);
       }
     });
diff --git a/src/timer.ts b/src/timer.ts
index 105fc8c7..2fc2ade0 100644
--- a/src/timer.ts
+++ b/src/timer.ts
@@ -54,7 +54,7 @@ export let performanceNow = (() => {
     return () => {
       const t = process.hrtime();
       return t[0] * 1e9 + t[1];
-    }
+    };
   } else if (typeof "performance" !== "undefined") {
     return () => performance.now();
   } else {
diff --git a/src/types-test.ts b/src/types-test.ts
index 88f9f272..a84bdaec 100644
--- a/src/types-test.ts
+++ b/src/types-test.ts
@@ -1,35 +1,51 @@
+/*
+ This file is part of TALER
+ (C) 2017 Inria and GNUnet e.V.
+
+ 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/>
+ */
+
 import {test} from "ava";
 import {Amounts} from "./types";
 import * as types from "./types";
 
-let amt = (value: number, fraction: number, currency: string): 
types.AmountJson => ({value, fraction, currency});
+const amt = (value: number, fraction: number, currency: string): 
types.AmountJson => ({value, fraction, currency});
 
-test("amount addition (simple)", t => {
-  let a1 = amt(1,0,"EUR");
-  let a2 = amt(1,0,"EUR");
-  let a3 = amt(2,0,"EUR");
-  t.true(0 == types.Amounts.cmp(Amounts.add(a1, a2).amount, a3));
+test("amount addition (simple)", (t) => {
+  const a1 = amt(1, 0, "EUR");
+  const a2 = amt(1, 0, "EUR");
+  const a3 = amt(2, 0, "EUR");
+  t.true(0 === types.Amounts.cmp(Amounts.add(a1, a2).amount, a3));
   t.pass();
 });
 
-test("amount addition (saturation)", t => {
-  let a1 = amt(1,0,"EUR");
-  let res = Amounts.add(Amounts.getMaxAmount("EUR"), a1);
+test("amount addition (saturation)", (t) => {
+  const a1 = amt(1, 0, "EUR");
+  const res = Amounts.add(Amounts.getMaxAmount("EUR"), a1);
   t.true(res.saturated);
   t.pass();
 });
 
-test("amount subtraction (simple)", t => {
-  let a1 = amt(2,5,"EUR");
-  let a2 = amt(1,0,"EUR");
-  let a3 = amt(1,5,"EUR");
-  t.true(0 == types.Amounts.cmp(Amounts.sub(a1, a2).amount, a3));
+test("amount subtraction (simple)", (t) => {
+  const a1 = amt(2, 5, "EUR");
+  const a2 = amt(1, 0, "EUR");
+  const a3 = amt(1, 5, "EUR");
+  t.true(0 === types.Amounts.cmp(Amounts.sub(a1, a2).amount, a3));
   t.pass();
 });
 
-test("amount subtraction (saturation)", t => {
-  let a1 = amt(0,0,"EUR");
-  let a2 = amt(1,0,"EUR");
+test("amount subtraction (saturation)", (t) => {
+  const a1 = amt(0, 0, "EUR");
+  const a2 = amt(1, 0, "EUR");
   let res = Amounts.sub(a1, a2);
   t.true(res.saturated);
   res = Amounts.sub(a1, a1);
@@ -38,29 +54,29 @@ test("amount subtraction (saturation)", t => {
 });
 
 
-test("contract validation", t => {
-  let c = {
+test("contract validation", (t) => {
+  const c = {
     H_wire: "123",
-    summary: "hello",
-    amount: amt(1,2,"EUR"),
+    amount: amt(1, 2, "EUR"),
     auditors: [],
-    pay_deadline: "Date(12346)",
-    max_fee: amt(1,2,"EUR"),
-    merchant_pub: "12345",
     exchanges: [{master_pub: "foo", url: "foo"}],
+    fulfillment_url: "foo",
+    max_fee: amt(1, 2, "EUR"),
+    merchant_pub: "12345",
+    order_id: "test_order",
+    pay_deadline: "Date(12346)",
+    pay_url: "https://example.com/pay";,
     products: [],
     refund_deadline: "Date(12345)",
+    summary: "hello",
     timestamp: "Date(12345)",
-    fulfillment_url: "foo",
     wire_method: "test",
-    order_id: "test_order",
-    pay_url: "https://example.com/pay";,
   };
 
   types.Contract.checked(c);
 
-  let c1 = JSON.parse(JSON.stringify(c));
-  c1.exchanges = []
+  const c1 = JSON.parse(JSON.stringify(c));
+  c1.exchanges = [];
 
   try {
     types.Contract.checked(c1);
@@ -70,5 +86,4 @@ test("contract validation", t => {
   }
 
   t.fail();
-
 });
diff --git a/src/types.ts b/src/types.ts
index 53f98948..91a61bc4 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -51,20 +51,20 @@ export interface SignedAmountJson {
 
 export interface ReserveRecord {
   reserve_pub: string;
-  reserve_priv: string,
-  exchange_base_url: string,
-  created: number,
-  last_query: number | null,
+  reserve_priv: string;
+  exchange_base_url: string;
+  created: number;
+  last_query: number | null;
   /**
    * Current amount left in the reserve
    */
-  current_amount: AmountJson | null,
+  current_amount: AmountJson | null;
   /**
    * Amount requested when the reserve was created.
    * When a reserve is re-used (rare!)  the current_amount can
    * be higher than the requested_amount
    */
-  requested_amount: AmountJson,
+  requested_amount: AmountJson;
 
 
   /**
@@ -360,7 +360,7 @@ export interface RefreshSessionRecord {
    * How much of the coin's value is melted away
    * with this refresh session?
    */
-  valueWithFee: AmountJson
+  valueWithFee: AmountJson;
 
   /**
    * Sum of the value of denominations we want
@@ -468,7 +468,7 @@ export interface CoinRecord {
    * Reserve public key for the reserve we got this coin from,
    * or zero when we got the coin from refresh.
    */
-  reservePub: string|undefined,
+  reservePub: string|undefined;
 
   /**
    * Status of the coin.
@@ -528,7 +528,7 @@ interface Merchant {
 export class Contract {
 
   validate() {
-    if (this.exchanges.length == 0) {
+    if (this.exchanges.length === 0) {
       throw Error("no exchanges in contract");
     }
   }
@@ -629,27 +629,27 @@ export namespace Amounts {
   export function getMaxAmount(currency: string): AmountJson {
     return {
       currency,
-      value: Number.MAX_SAFE_INTEGER,
       fraction: 2 ** 32,
-    }
+      value: Number.MAX_SAFE_INTEGER,
+    };
   }
 
   export function getZero(currency: string): AmountJson {
     return {
       currency,
-      value: 0,
       fraction: 0,
-    }
+      value: 0,
+    };
   }
 
   export function add(first: AmountJson, ...rest: AmountJson[]): Result {
-    let currency = first.currency;
+    const currency = first.currency;
     let value = first.value + Math.floor(first.fraction / fractionalBase);
     if (value > Number.MAX_SAFE_INTEGER) {
       return { amount: getMaxAmount(currency), saturated: true };
     }
     let fraction = first.fraction % fractionalBase;
-    for (let x of rest) {
+    for (const x of rest) {
       if (x.currency !== currency) {
         throw Error(`Mismatched currency: ${x.currency} and ${currency}`);
       }
@@ -665,11 +665,11 @@ export namespace Amounts {
 
 
   export function sub(a: AmountJson, ...rest: AmountJson[]): Result {
-    let currency = a.currency;
+    const currency = a.currency;
     let value = a.value;
     let fraction = a.fraction;
 
-    for (let b of rest) {
+    for (const b of rest) {
       if (b.currency !== currency) {
         throw Error(`Mismatched currency: ${b.currency} and ${currency}`);
       }
@@ -695,10 +695,10 @@ export namespace Amounts {
     if (a.currency !== b.currency) {
       throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
     }
-    let av = a.value + Math.floor(a.fraction / fractionalBase);
-    let af = a.fraction % fractionalBase;
-    let bv = b.value + Math.floor(b.fraction / fractionalBase);
-    let bf = b.fraction % fractionalBase;
+    const av = a.value + Math.floor(a.fraction / fractionalBase);
+    const af = a.fraction % fractionalBase;
+    const bv = b.value + Math.floor(b.fraction / fractionalBase);
+    const bf = b.fraction % fractionalBase;
     switch (true) {
       case av < bv:
         return -1;
@@ -708,7 +708,7 @@ export namespace Amounts {
         return -1;
       case af > bf:
         return 1;
-      case af == bf:
+      case af === bf:
         return 0;
       default:
         throw Error("assertion failed");
@@ -717,25 +717,25 @@ export namespace Amounts {
 
   export function copy(a: AmountJson): AmountJson {
     return {
-      value: a.value,
-      fraction: a.fraction,
       currency: a.currency,
-    }
+      fraction: a.fraction,
+      value: a.value,
+    };
   }
 
   export function divide(a: AmountJson, n: number): AmountJson {
-    if (n == 0) {
+    if (n === 0) {
       throw Error(`Division by 0`);
     }
-    if (n == 1) {
+    if (n === 1) {
       return {value: a.value, fraction: a.fraction, currency: a.currency};
     }
-    let r = a.value % n;
+    const r = a.value % n;
     return {
       currency: a.currency,
-      value: Math.floor(a.value / n),
       fraction: Math.floor(((r * fractionalBase) + a.fraction) / n),
-    }
+      value: Math.floor(a.value / n),
+    };
   }
 
   export function isNonZero(a: AmountJson) {
@@ -746,15 +746,15 @@ export namespace Amounts {
    * Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
    */
   export function parse(s: string): AmountJson|undefined {
-    let res = s.match(/([a-zA-Z0-9_*-]+):([0-9])+([.][0-9]+)?/);
+    const res = s.match(/([a-zA-Z0-9_*-]+):([0-9])+([.][0-9]+)?/);
     if (!res) {
       return undefined;
     }
     return {
       currency: res[1],
-      value: Number.parseInt(res[2]),
       fraction: Math.round(fractionalBase * Number.parseFloat(res[3] || "0")),
-    }
+      value: Number.parseInt(res[2]),
+    };
   }
 }
 
diff --git a/src/wallet-test.ts b/src/wallet-test.ts
index 2c3ed52d..51a8497b 100644
--- a/src/wallet-test.ts
+++ b/src/wallet-test.ts
@@ -1,135 +1,152 @@
+/*
+ This file is part of TALER
+ (C) 2017 Inria and GNUnet e.V.
+
+ 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/>
+ */
+
+
 import {test} from "ava";
 import * as types from "./types";
 import * as wallet from "./wallet";
 
+
 function a(x: string): types.AmountJson {
-  let amt = types.Amounts.parse(x);
+  const amt = types.Amounts.parse(x);
   if (!amt) {
     throw Error("invalid amount");
   }
   return amt;
 }
 
+
 function fakeCwd(current: string, value: string, feeDeposit: string): 
wallet.CoinWithDenom {
   return {
     coin: {
-      currentAmount: a(current),
-      coinPub: "(mock)",
+      blindingKey: "(mock)",
       coinPriv: "(mock)",
+      coinPub: "(mock)",
+      currentAmount: a(current),
       denomPub: "(mock)",
       denomSig: "(mock)",
       exchangeBaseUrl: "(mock)",
-      blindingKey: "(mock)",
       reservePub: "(mock)",
       status: types.CoinStatus.Fresh,
     },
     denom: {
-      value: a(value),
-      feeDeposit: a(feeDeposit),
       denomPub: "(mock)",
       denomPubHash: "(mock)",
-      feeWithdraw: a("EUR:0.0"),
+      exchangeBaseUrl: "(mock)",
+      feeDeposit: a(feeDeposit),
       feeRefresh: a("EUR:0.0"),
       feeRefund: a("EUR:0.0"),
-      stampStart: "(mock)",
-      stampExpireWithdraw: "(mock)",
-      stampExpireLegal: "(mock)",
-      stampExpireDeposit: "(mock)",
+      feeWithdraw: a("EUR:0.0"),
+      isOffered: true,
       masterSig: "(mock)",
+      stampExpireDeposit: "(mock)",
+      stampExpireLegal: "(mock)",
+      stampExpireWithdraw: "(mock)",
+      stampStart: "(mock)",
       status: types.DenominationStatus.VerifiedGood,
-      isOffered: true,
-      exchangeBaseUrl: "(mock)",
+      value: a(value),
     },
-  }
+  };
 }
 
 
-
-test("coin selection 1", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 1", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.1"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
   ];
 
-  let res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.1"));
+  const res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.1"));
   if (!res) {
     t.fail();
     return;
   }
-  t.true(res.length == 2);
+  t.true(res.length === 2);
   t.pass();
 });
 
 
-test("coin selection 2", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 2", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
     // Merchant covers the fee, this one shouldn't be used
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
   ];
-  let res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
+  const res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
   if (!res) {
     t.fail();
     return;
   }
-  t.true(res.length == 2);
+  t.true(res.length === 2);
   t.pass();
 });
 
 
-test("coin selection 3", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 3", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     // this coin should be selected instead of previous one with fee
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
   ];
-  let res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
+  const res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
   if (!res) {
     t.fail();
     return;
   }
-  t.true(res.length == 2);
+  t.true(res.length === 2);
   t.pass();
 });
 
 
-
-test("coin selection 4", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 4", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
   ];
-  let res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
+  const res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
   if (!res) {
     t.fail();
     return;
   }
-  t.true(res.length == 3);
+  t.true(res.length === 3);
   t.pass();
 });
 
 
-test("coin selection 5", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 5", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
   ];
-  let res = wallet.selectCoins(cds, a("EUR:4.0"), a("EUR:0.2"));
+  const res = wallet.selectCoins(cds, a("EUR:4.0"), a("EUR:0.2"));
   t.true(!res);
   t.pass();
 });
 
 
-test("coin selection 6", t => {
-  let cds: wallet.CoinWithDenom[] = [
+test("coin selection 6", (t) => {
+  const cds: wallet.CoinWithDenom[] = [
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
     fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
   ];
-  let res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
+  const res = wallet.selectCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
   t.true(!res);
   t.pass();
 });
diff --git a/src/wallet.ts b/src/wallet.ts
index a2a9e83f..b21cdbd9 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -22,57 +22,58 @@
 /**
  * Imports.
  */
+import {Checkable} from "./checkable";
+import {CryptoApi} from "./crypto/cryptoApi";
+import {
+  amountToPretty,
+  canonicalJson,
+  canonicalizeBaseUrl,
+  deepEquals,
+  flatMap,
+  getTalerStampSec,
+} from "./helpers";
+import {
+  HttpRequestLibrary,
+  HttpResponse,
+  RequestException,
+} from "./http";
+import {
+  AbortTransaction,
+  Index,
+  JoinLeftResult,
+  JoinResult,
+  QueryRoot,
+  Store,
+} from "./query";
 import {
   AmountJson,
   Amounts,
-  CoinRecord,
+  Auditor,
+  AuditorRecord,
   CoinPaySig,
+  CoinRecord,
+  CoinStatus,
   Contract,
   CreateReserveResponse,
+  CurrencyRecord,
   Denomination,
+  DenominationRecord,
+  DenominationStatus,
   ExchangeHandle,
   ExchangeRecord,
+  ExchangeWireFeesRecord,
   Notifier,
   PayCoinInfo,
+  PaybackConfirmation,
   PreCoinRecord,
   RefreshSessionRecord,
   ReserveCreationInfo,
   ReserveRecord,
-  CurrencyRecord,
-  Auditor,
-  AuditorRecord,
   WalletBalance,
   WalletBalanceEntry,
   WireFee,
-  ExchangeWireFeesRecord,
   WireInfo,
-  DenominationRecord,
-  DenominationStatus,
-  CoinStatus,
-  PaybackConfirmation,
 } from "./types";
-import {
-  HttpRequestLibrary,
-  HttpResponse,
-  RequestException,
-} from "./http";
-import {
-  AbortTransaction,
-  Index,
-  JoinResult,
-  QueryRoot,
-  Store, JoinLeftResult,
-} from "./query";
-import {Checkable} from "./checkable";
-import {
-  amountToPretty,
-  canonicalizeBaseUrl,
-  canonicalJson,
-  deepEquals,
-  flatMap,
-  getTalerStampSec,
-} from "./helpers";
-import {CryptoApi} from "./crypto/cryptoApi";
 import URI = require("urijs");
 
 
@@ -272,33 +273,31 @@ export interface ConfigRecord {
 }
 
 
-
 const builtinCurrencies: CurrencyRecord[] = [
   {
-    name: "KUDOS",
-    fractionalDigits: 2,
     auditors: [
       {
+        auditorPub: "XN9KMN5G2KGPCAN0E89MM5HE8FV4WBWA9KDTMTDR817MWBCYA7H0",
         baseUrl: "https://auditor.demo.taler.net/";,
         expirationStamp: (new Date(2027, 1)).getTime(),
-        auditorPub: "XN9KMN5G2KGPCAN0E89MM5HE8FV4WBWA9KDTMTDR817MWBCYA7H0",
       },
     ],
     exchanges: [],
+    fractionalDigits: 2,
+    name: "KUDOS",
   },
   {
-    name: "PUDOS",
-    fractionalDigits: 2,
     auditors: [
     ],
     exchanges: [
       { baseUrl: "https://exchange.test.taler.net/";, priority: 0 },
     ],
+    fractionalDigits: 2,
+    name: "PUDOS",
   },
 ];
 
 
-
 // FIXME: these functions should be dependency-injected
 // into the wallet, as this is chrome specific => bad
 
@@ -312,17 +311,17 @@ function setInterval(f: any, t: number) {
 
 
 function isWithdrawableDenom(d: DenominationRecord) {
-  const now_sec = (new Date).getTime() / 1000;
-  const stamp_withdraw_sec = getTalerStampSec(d.stampExpireWithdraw);
-  if (stamp_withdraw_sec == null) {
+  const nowSec = (new Date()).getTime() / 1000;
+  const stampWithdrawSec = getTalerStampSec(d.stampExpireWithdraw);
+  if (stampWithdrawSec === null) {
     return false;
   }
-  const stamp_start_sec = getTalerStampSec(d.stampStart);
-  if (stamp_start_sec == null) {
+  const stampStartSec = getTalerStampSec(d.stampStart);
+  if (stampStartSec === null) {
     return false;
   }
   // Withdraw if still possible to withdraw within a minute
-  if ((stamp_withdraw_sec + 60 > now_sec) && (now_sec >= stamp_start_sec)) {
+  if ((stampWithdrawSec + 60 > nowSec) && (nowSec >= stampStartSec)) {
     return true;
   }
   return false;
@@ -333,31 +332,30 @@ export type CoinSelectionResult = {exchangeUrl: string, 
cds: CoinWithDenom[]}|un
 
 export function selectCoins(cds: CoinWithDenom[], paymentAmount: AmountJson,
                             depositFeeLimit: AmountJson): 
CoinWithDenom[]|undefined {
-  if (cds.length == 0) {
+  if (cds.length === 0) {
     return undefined;
   }
   // Sort by ascending deposit fee
   cds.sort((o1, o2) => Amounts.cmp(o1.denom.feeDeposit,
                                    o2.denom.feeDeposit));
-  let currency = cds[0].denom.value.currency;
-  let cdsResult: CoinWithDenom[] = [];
+  const currency = cds[0].denom.value.currency;
+  const cdsResult: CoinWithDenom[] = [];
   let accFee: AmountJson = Amounts.getZero(currency);
   let accAmount: AmountJson = Amounts.getZero(currency);
   let isBelowFee = false;
   let coversAmount = false;
   let coversAmountWithFee = false;
-  for (let i = 0; i < cds.length; i++) {
-    let {coin, denom} = cds[i];
+  for (const {coin, denom} of cds) {
     if (coin.suspended) {
       continue;
     }
-    if (coin.status != CoinStatus.Fresh) {
+    if (coin.status !== CoinStatus.Fresh) {
       continue;
     }
     if (Amounts.cmp(denom.feeDeposit, coin.currentAmount) >= 0) {
       continue;
     }
-    cdsResult.push(cds[i]);
+    cdsResult.push({coin, denom});
     accFee = Amounts.add(denom.feeDeposit, accFee).amount;
     accAmount = Amounts.add(coin.currentAmount, accAmount).amount;
     coversAmount = Amounts.cmp(accAmount, paymentAmount) >= 0;
@@ -391,8 +389,8 @@ function getWithdrawDenomList(amountAvailable: AmountJson,
   // is useful ...
   for (let i = 0; i < 1000; i++) {
     let found = false;
-    for (let d of denoms) {
-      let cost = Amounts.add(d.value, d.feeWithdraw).amount;
+    for (const d of denoms) {
+      const cost = Amounts.add(d.value, d.feeWithdraw).amount;
       if (Amounts.cmp(remaining, cost) < 0) {
         continue;
       }
@@ -415,7 +413,7 @@ export namespace Stores {
       super("exchanges", {keyPath: "baseUrl"});
     }
 
-    pubKeyIndex = new Index<string,ExchangeRecord>(this, "pubKey", 
"masterPublicKey");
+    pubKeyIndex = new Index<string, ExchangeRecord>(this, "pubKey", 
"masterPublicKey");
   }
 
   class NonceStore extends Store<NonceRecord> {
@@ -429,26 +427,26 @@ export namespace Stores {
       super("coins", {keyPath: "coinPub"});
     }
 
-    exchangeBaseUrlIndex = new Index<string,CoinRecord>(this, 
"exchangeBaseUrl", "exchangeBaseUrl");
-    denomPubIndex = new Index<string,CoinRecord>(this, "denomPub", "denomPub");
+    exchangeBaseUrlIndex = new Index<string, CoinRecord>(this, 
"exchangeBaseUrl", "exchangeBaseUrl");
+    denomPubIndex = new Index<string, CoinRecord>(this, "denomPub", 
"denomPub");
   }
 
   class HistoryStore extends Store<HistoryRecord> {
     constructor() {
       super("history", {
+        autoIncrement: true,
         keyPath: "id",
-        autoIncrement: true
       });
     }
 
-    timestampIndex = new Index<number,HistoryRecord>(this, "timestamp", 
"timestamp");
+    timestampIndex = new Index<number, HistoryRecord>(this, "timestamp", 
"timestamp");
   }
 
   class OffersStore extends Store<OfferRecord> {
     constructor() {
       super("offers", {
+        autoIncrement: true,
         keyPath: "id",
-        autoIncrement: true
       });
     }
   }
@@ -458,8 +456,8 @@ export namespace Stores {
       super("transactions", {keyPath: "contractHash"});
     }
 
-    fulfillmentUrlIndex = new Index<string,TransactionRecord>(this, 
"fulfillment_url", "contract.fulfillment_url");
-    orderIdIndex = new Index<string,TransactionRecord>(this, "order_id", 
"contract.order_id");
+    fulfillmentUrlIndex = new Index<string, TransactionRecord>(this, 
"fulfillment_url", "contract.fulfillment_url");
+    orderIdIndex = new Index<string, TransactionRecord>(this, "order_id", 
"contract.order_id");
   }
 
   class DenominationsStore extends Store<DenominationRecord> {
@@ -469,7 +467,7 @@ export namespace Stores {
             {keyPath: ["exchangeBaseUrl", "denomPub"] as any as IDBKeyPath});
     }
 
-    denomPubHashIndex = new Index<string,DenominationRecord>(this, 
"denomPubHash", "denomPubHash");
+    denomPubHashIndex = new Index<string, DenominationRecord>(this, 
"denomPubHash", "denomPubHash");
     exchangeBaseUrlIndex = new Index<string, DenominationRecord>(this, 
"exchangeBaseUrl", "exchangeBaseUrl");
     denomPubIndex = new Index<string, DenominationRecord>(this, "denomPub", 
"denomPub");
   }
@@ -491,19 +489,31 @@ export namespace Stores {
       super("exchangeWireFees", {keyPath: "exchangeBaseUrl"});
     }
   }
-  export const exchanges: ExchangeStore = new ExchangeStore();
-  export const exchangeWireFees: ExchangeWireFeesStore = new 
ExchangeWireFeesStore();
-  export const nonces: NonceStore = new NonceStore();
-  export const transactions: TransactionsStore = new TransactionsStore();
-  export const reserves: Store<ReserveRecord> = new 
Store<ReserveRecord>("reserves", {keyPath: "reserve_pub"});
-  export const coins: CoinsStore = new CoinsStore();
-  export const refresh: Store<RefreshSessionRecord> = new 
Store<RefreshSessionRecord>("refresh", {keyPath: "meltCoinPub"});
-  export const history: HistoryStore = new HistoryStore();
-  export const offers: OffersStore = new OffersStore();
-  export const precoins: Store<PreCoinRecord> = new 
Store<PreCoinRecord>("precoins", {keyPath: "coinPub"});
-  export const denominations: DenominationsStore = new DenominationsStore();
-  export const currencies: CurrenciesStore = new CurrenciesStore();
-  export const config: ConfigStore = new ConfigStore();
+  export const exchanges = new ExchangeStore();
+  export const exchangeWireFees = new ExchangeWireFeesStore();
+  export const nonces = new NonceStore();
+  export const transactions = new TransactionsStore();
+  export const reserves = new Store<ReserveRecord>("reserves", {keyPath: 
"reserve_pub"});
+  export const coins = new CoinsStore();
+  export const refresh = new Store<RefreshSessionRecord>("refresh", {keyPath: 
"meltCoinPub"});
+  export const history = new HistoryStore();
+  export const offers = new OffersStore();
+  export const precoins = new Store<PreCoinRecord>("precoins", {keyPath: 
"coinPub"});
+  export const denominations = new DenominationsStore();
+  export const currencies = new CurrenciesStore();
+  export const config = new ConfigStore();
+}
+
+
+interface CoinsForPaymentArgs {
+  allowedAuditors: Auditor[];
+  allowedExchanges: ExchangeHandle[];
+  depositFeeLimit: AmountJson;
+  paymentAmount: AmountJson;
+  wireFeeAmortization: number;
+  wireFeeLimit: AmountJson;
+  wireFeeTime: number;
+  wireMethod: string;
 }
 
 
@@ -543,10 +553,10 @@ export class Wallet {
   }
 
   private async fillDefaults() {
-    let onTrue = (r: QueryRoot) => {
+    const onTrue = (r: QueryRoot) => {
       console.log("defaults already applied");
     };
-    let onFalse = (r: QueryRoot) => {
+    const onFalse = (r: QueryRoot) => {
       console.log("applying defaults");
       r.put(Stores.config, {key: "currencyDefaultsApplied", value: true})
         .putAll(Stores.currencies, builtinCurrencies)
@@ -555,7 +565,7 @@ export class Wallet {
     await (
       this.q()
           .iter(Stores.config)
-          .filter(x => x.key == "currencyDefaultsApplied")
+          .filter((x) => x.key === "currencyDefaultsApplied")
           .first()
           .cond((x) => x && x.value, onTrue, onFalse)
     );
@@ -569,7 +579,7 @@ export class Wallet {
 
   private stopOperation(operationId: string) {
     this.runningOperations.delete(operationId);
-    if (this.runningOperations.size == 0) {
+    if (this.runningOperations.size === 0) {
       this.badge.stopBusy();
     }
   }
@@ -577,12 +587,12 @@ export class Wallet {
   async updateExchanges(): Promise<void> {
     console.log("updating exchanges");
 
-    let exchangesUrls = await this.q()
-                                  .iter(Stores.exchanges)
-                                  .map((e) => e.baseUrl)
-                                  .toArray();
+    const exchangesUrls = await this.q()
+                                   .iter(Stores.exchanges)
+                                   .map((e) => e.baseUrl)
+                                   .toArray();
 
-    for (let url of exchangesUrls) {
+    for (const url of exchangesUrls) {
       this.updateExchangeFromUrl(url)
           .catch((e) => {
             console.error("updating exchange failed", e);
@@ -621,7 +631,7 @@ export class Wallet {
     this.q()
         .iter(Stores.coins)
         .reduce((c: CoinRecord) => {
-          if (c.status == CoinStatus.Dirty) {
+          if (c.status === CoinStatus.Dirty) {
             console.log("resuming pending refresh for coin", c);
             this.refresh(c.coinPub);
           }
@@ -633,23 +643,28 @@ export class Wallet {
    * Get exchanges and associated coins that are still spendable,
    * but only if the sum the coins' remaining value exceeds the payment amount.
    */
-  private async getCoinsForPayment(paymentAmount: AmountJson,
-                                   wireMethod: string,
-                                   wireFeeTime: number,
-                                   depositFeeLimit: AmountJson,
-                                   wireFeeLimit: AmountJson,
-                                   wireFeeAmortization: number,
-                                   allowedExchanges: ExchangeHandle[],
-                                   allowedAuditors: Auditor[]): 
Promise<CoinSelectionResult> {
-
-    let exchanges = await this.q().iter(Stores.exchanges).toArray();
-
-    for (let exchange of exchanges) {
+  private async getCoinsForPayment(args: CoinsForPaymentArgs): 
Promise<CoinSelectionResult> {
+    const {
+      allowedAuditors,
+      allowedExchanges,
+      depositFeeLimit,
+      paymentAmount,
+      wireFeeAmortization,
+      wireFeeLimit,
+      wireFeeTime,
+      wireMethod,
+    } = args;
+
+    let remainingAmount = paymentAmount;
+
+    const exchanges = await this.q().iter(Stores.exchanges).toArray();
+
+    for (const exchange of exchanges) {
       let isOkay: boolean = false;
 
       // is the exchange explicitly allowed?
-      for (let allowedExchange of allowedExchanges) {
-        if (allowedExchange.master_pub == exchange.masterPublicKey) {
+      for (const allowedExchange of allowedExchanges) {
+        if (allowedExchange.master_pub === exchange.masterPublicKey) {
           isOkay = true;
           break;
         }
@@ -657,9 +672,9 @@ export class Wallet {
 
       // is the exchange allowed because of one of its auditors?
       if (!isOkay) {
-        for (let allowedAuditor of allowedAuditors) {
-          for (let auditor of exchange.auditors) {
-            if (auditor.auditor_pub == allowedAuditor.auditor_pub) {
+        for (const allowedAuditor of allowedAuditors) {
+          for (const auditor of exchange.auditors) {
+            if (auditor.auditor_pub === allowedAuditor.auditor_pub) {
               isOkay = true;
               break;
             }
@@ -674,53 +689,52 @@ export class Wallet {
         continue;
       }
 
-      let coins: CoinRecord[] = await this.q()
+      const coins: CoinRecord[] = await this.q()
                                           
.iterIndex(Stores.coins.exchangeBaseUrlIndex,
                                                      exchange.baseUrl)
                                           .toArray();
-      if (!coins || coins.length == 0) {
+      if (!coins || coins.length === 0) {
         continue;
       }
       // Denomination of the first coin, we assume that all other
       // coins have the same currency
-      let firstDenom = await this.q().get(Stores.denominations,
-                                          [
-                                            exchange.baseUrl,
-                                            coins[0].denomPub
-                                          ]);
+      const firstDenom = await this.q().get(Stores.denominations,
+                                            [
+                                              exchange.baseUrl,
+                                              coins[0].denomPub,
+                                            ]);
       if (!firstDenom) {
         throw Error("db inconsistent");
       }
-      let currency = firstDenom.value.currency;
-      let cds: CoinWithDenom[] = [];
-      for (let i = 0; i < coins.length; i++) {
-        let coin = coins[i];
-        let denom = await this.q().get(Stores.denominations,
+      const currency = firstDenom.value.currency;
+      const cds: CoinWithDenom[] = [];
+      for (const coin of coins) {
+        const denom = await this.q().get(Stores.denominations,
                                        [exchange.baseUrl, coin.denomPub]);
         if (!denom) {
           throw Error("db inconsistent");
         }
-        if (denom.value.currency != currency) {
+        if (denom.value.currency !== currency) {
           console.warn(`same pubkey for different currencies at exchange 
${exchange.baseUrl}`);
           continue;
         }
         if (coin.suspended) {
           continue;
         }
-        if (coin.status != CoinStatus.Fresh) {
+        if (coin.status !== CoinStatus.Fresh) {
           continue;
         }
         cds.push({coin, denom});
       }
 
-      let fees = await this.q().get(Stores.exchangeWireFees, exchange.baseUrl);
+      const fees = await this.q().get(Stores.exchangeWireFees, 
exchange.baseUrl);
       if (!fees) {
         console.error("no fees found for exchange", exchange);
         continue;
       }
 
-      let wireFee: AmountJson|undefined = undefined;
-      for (let fee of (fees.feesForType[wireMethod] || [])) {
+      let wireFee: AmountJson|undefined;
+      for (const fee of (fees.feesForType[wireMethod] || [])) {
         if (fee.startStamp >= wireFeeTime && fee.endStamp <= wireFeeTime) {
           wireFee = fee.wireFee;
           break;
@@ -728,18 +742,18 @@ export class Wallet {
       }
 
       if (wireFee) {
-        let amortizedWireFee = Amounts.divide(wireFee, wireFeeAmortization);
+        const amortizedWireFee = Amounts.divide(wireFee, wireFeeAmortization);
         if (Amounts.cmp(wireFeeLimit, amortizedWireFee) < 0) {
-          paymentAmount = Amounts.add(amortizedWireFee, paymentAmount).amount;
+          remainingAmount = Amounts.add(amortizedWireFee, 
remainingAmount).amount;
         }
       }
 
-      let res = selectCoins(cds, paymentAmount, depositFeeLimit);
+      const res = selectCoins(cds, remainingAmount, depositFeeLimit);
       if (res) {
         return {
-          exchangeUrl: exchange.baseUrl,
           cds: res,
-        }
+          exchangeUrl: exchange.baseUrl,
+        };
       }
     }
     return undefined;
@@ -753,31 +767,31 @@ export class Wallet {
   private async recordConfirmPay(offer: OfferRecord,
                                  payCoinInfo: PayCoinInfo,
                                  chosenExchange: string): Promise<void> {
-    let payReq: PayReq = {
+    const payReq: PayReq = {
       coins: payCoinInfo.map((x) => x.sig),
+      exchange: chosenExchange,
       merchant_pub: offer.contract.merchant_pub,
       order_id: offer.contract.order_id,
-      exchange: chosenExchange,
     };
-    let t: TransactionRecord = {
-      contractHash: offer.H_contract,
+    const t: TransactionRecord = {
       contract: offer.contract,
-      payReq: payReq,
-      merchantSig: offer.merchant_sig,
+      contractHash: offer.H_contract,
       finished: false,
+      merchantSig: offer.merchant_sig,
+      payReq,
     };
 
-    let historyEntry: HistoryRecord = {
-      type: "pay",
-      timestamp: (new Date).getTime(),
-      subjectId: `contract-${offer.H_contract}`,
+    const historyEntry: HistoryRecord = {
       detail: {
-        merchantName: offer.contract.merchant.name,
         amount: offer.contract.amount,
         contractHash: offer.H_contract,
         fulfillmentUrl: offer.contract.fulfillment_url,
+        merchantName: offer.contract.merchant.name,
       },
-      level: HistoryLevel.User
+      level: HistoryLevel.User,
+      subjectId: `contract-${offer.H_contract}`,
+      timestamp: (new Date()).getTime(),
+      type: "pay",
     };
 
     await this.q()
@@ -798,7 +812,7 @@ export class Wallet {
 
   async saveOffer(offer: OfferRecord): Promise<number> {
     console.log(`saving offer in wallet.ts`);
-    let id = await this.q().putWithResult(Stores.offers, offer);
+    const id = await this.q().putWithResult(Stores.offers, offer);
     this.notifier.notify();
     console.log(`saved offer with id ${id}`);
     if (typeof id !== "number") {
@@ -815,21 +829,23 @@ export class Wallet {
   async confirmPay(offer: OfferRecord): Promise<any> {
     console.log("executing confirmPay");
 
-    let transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
+    const transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
 
     if (transaction) {
       // Already payed ...
       return {};
     }
 
-    let res = await this.getCoinsForPayment(offer.contract.amount,
-                                            offer.contract.wire_method,
-                                            
getTalerStampSec(offer.contract.timestamp) || 0,
-                                            offer.contract.max_fee,
-                                            offer.contract.max_wire_fee || 
Amounts.getZero(offer.contract.amount.currency),
-                                            
offer.contract.wire_fee_amortization || 1,
-                                            offer.contract.exchanges,
-                                            offer.contract.auditors);
+    const res = await this.getCoinsForPayment({
+      allowedAuditors: offer.contract.auditors,
+      allowedExchanges: offer.contract.exchanges,
+      depositFeeLimit: offer.contract.max_fee,
+      paymentAmount: offer.contract.amount,
+      wireFeeAmortization: offer.contract.wire_fee_amortization || 1,
+      wireFeeLimit: offer.contract.max_wire_fee || 
Amounts.getZero(offer.contract.amount.currency),
+      wireFeeTime: getTalerStampSec(offer.contract.timestamp) || 0,
+      wireMethod: offer.contract.wire_method,
+    });
 
     console.log("max_fee", offer.contract.max_fee);
     console.log("coin selection result", res);
@@ -840,9 +856,9 @@ export class Wallet {
         error: "coins-insufficient",
       };
     }
-    let {exchangeUrl, cds} = res;
+    const {exchangeUrl, cds} = res;
 
-    let ds = await this.cryptoApi.signDeposit(offer, cds);
+    const ds = await this.cryptoApi.signDeposit(offer, cds);
     await this.recordConfirmPay(offer,
                                 ds,
                                 exchangeUrl);
@@ -856,20 +872,22 @@ export class Wallet {
    */
   async checkPay(offer: OfferRecord): Promise<any> {
     // First check if we already payed for it.
-    let transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
+    const transaction = await this.q().get(Stores.transactions, 
offer.H_contract);
     if (transaction) {
       return {isPayed: true};
     }
 
     // If not already payed, check if we could pay for it.
-    let res = await this.getCoinsForPayment(offer.contract.amount,
-                                            offer.contract.wire_method,
-                                            
getTalerStampSec(offer.contract.timestamp) || 0,
-                                            offer.contract.max_fee,
-                                            offer.contract.max_wire_fee || 
Amounts.getZero(offer.contract.amount.currency),
-                                            
offer.contract.wire_fee_amortization || 1,
-                                            offer.contract.exchanges,
-                                            offer.contract.auditors);
+    const res = await this.getCoinsForPayment({
+      allowedAuditors: offer.contract.auditors,
+      allowedExchanges: offer.contract.exchanges,
+      depositFeeLimit: offer.contract.max_fee,
+      paymentAmount: offer.contract.amount,
+      wireFeeAmortization: offer.contract.wire_fee_amortization || 1,
+      wireFeeLimit: offer.contract.max_wire_fee || 
Amounts.getZero(offer.contract.amount.currency),
+      wireFeeTime: getTalerStampSec(offer.contract.timestamp) || 0,
+      wireMethod: offer.contract.wire_method,
+    });
 
     if (!res) {
       console.log("not confirming payment, insufficient coins");
@@ -894,14 +912,14 @@ export class Wallet {
       console.log("query for payment failed");
       return {
         success: false,
-      }
+      };
     }
     console.log("query for payment succeeded:", t);
-    let resp = {
-      success: true,
-      payReq: t.payReq,
+    const resp = {
       H_contract: t.contractHash,
       contract: t.contract,
+      payReq: t.payReq,
+      success: true,
     };
     return resp;
   }
@@ -917,29 +935,28 @@ export class Wallet {
     this.startOperation(opId);
 
     try {
-      let exchange = await 
this.updateExchangeFromUrl(reserveRecord.exchange_base_url);
-      let reserve = await this.updateReserve(reserveRecord.reserve_pub);
-      let n = await this.depleteReserve(reserve);
+      const exchange = await 
this.updateExchangeFromUrl(reserveRecord.exchange_base_url);
+      const reserve = await this.updateReserve(reserveRecord.reserve_pub);
+      const n = await this.depleteReserve(reserve);
 
-      if (n != 0) {
-        let depleted: HistoryRecord = {
-          type: "depleted-reserve",
-          subjectId: `reserve-progress-${reserveRecord.reserve_pub}`,
-          timestamp: (new Date).getTime(),
+      if (n !== 0) {
+        const depleted: HistoryRecord = {
           detail: {
+            currentAmount: reserveRecord.current_amount,
             exchangeBaseUrl: reserveRecord.exchange_base_url,
-            reservePub: reserveRecord.reserve_pub,
             requestedAmount: reserveRecord.requested_amount,
-            currentAmount: reserveRecord.current_amount,
+            reservePub: reserveRecord.reserve_pub,
           },
-          level: HistoryLevel.User
+          level: HistoryLevel.User,
+          subjectId: `reserve-progress-${reserveRecord.reserve_pub}`,
+          timestamp: (new Date()).getTime(),
+          type: "depleted-reserve",
         };
         await this.q().put(Stores.history, depleted).finish();
       }
     } catch (e) {
       // random, exponential backoff truncated at 3 minutes
-      let nextDelay = Math.min(2 * retryDelayMs + retryDelayMs * Math.random(),
-                               3000 * 60);
+      const nextDelay = Math.min(2 * retryDelayMs + retryDelayMs * 
Math.random(), 3000 * 60);
       console.warn(`Failed to deplete reserve, trying again in ${retryDelayMs} 
ms`);
       setTimeout(() => this.processReserve(reserveRecord, nextDelay),
                  retryDelayMs);
@@ -980,9 +997,7 @@ export class Wallet {
         console.log(`before committing coin: current 
${amountToPretty(r.current_amount!)}, precoin: ${amountToPretty(
           r.precoin_amount)})}`);
 
-        let x = Amounts.sub(r.precoin_amount,
-                            preCoin.coinValue,
-                            denom.feeWithdraw);
+        const x = Amounts.sub(r.precoin_amount, preCoin.coinValue, 
denom.feeWithdraw);
         if (x.saturated) {
           console.error("database inconsistent");
           throw AbortTransaction;
@@ -992,12 +1007,12 @@ export class Wallet {
       };
 
       const historyEntry: HistoryRecord = {
-        type: "withdraw",
-        timestamp: (new Date).getTime(),
-        level: HistoryLevel.Expert,
         detail: {
           coinPub: coin.coinPub,
-        }
+        },
+        level: HistoryLevel.Expert,
+        timestamp: (new Date()).getTime(),
+        type: "withdraw",
       };
 
       await this.q()
@@ -1013,10 +1028,12 @@ export class Wallet {
                     retryDelayMs,
                     "ms", e);
       // exponential backoff truncated at one minute
-      let nextRetryDelayMs = Math.min(retryDelayMs * 2, 5 * 60 * 1000);
+      const nextRetryDelayMs = Math.min(retryDelayMs * 2, 5 * 60 * 1000);
       setTimeout(() => this.processPreCoin(preCoin, nextRetryDelayMs),
                  retryDelayMs);
-      this.processPreCoinThrottle[preCoin.exchangeBaseUrl] = 
(this.processPreCoinThrottle[preCoin.exchangeBaseUrl] || 0) + 1;
+
+      const currentThrottle = 
this.processPreCoinThrottle[preCoin.exchangeBaseUrl] || 0;
+      this.processPreCoinThrottle[preCoin.exchangeBaseUrl] = currentThrottle + 
1;
       setTimeout(() => 
{this.processPreCoinThrottle[preCoin.exchangeBaseUrl]--; }, retryDelayMs);
     } finally {
       this.processPreCoinConcurrent--;
@@ -1031,44 +1048,44 @@ export class Wallet {
    * audited nor trusted already.
    */
   async createReserve(req: CreateReserveRequest): 
Promise<CreateReserveResponse> {
-    let keypair = await this.cryptoApi.createEddsaKeypair();
-    const now = (new Date).getTime();
+    const keypair = await this.cryptoApi.createEddsaKeypair();
+    const now = (new Date()).getTime();
     const canonExchange = canonicalizeBaseUrl(req.exchange);
 
     const reserveRecord: ReserveRecord = {
-      hasPayback: false,
-      reserve_pub: keypair.pub,
-      reserve_priv: keypair.priv,
-      exchange_base_url: canonExchange,
+      confirmed: false,
       created: now,
-      last_query: null,
       current_amount: null,
-      requested_amount: req.amount,
-      confirmed: false,
+      exchange_base_url: canonExchange,
+      hasPayback: false,
+      last_query: null,
       precoin_amount: Amounts.getZero(req.amount.currency),
+      requested_amount: req.amount,
+      reserve_priv: keypair.priv,
+      reserve_pub: keypair.pub,
     };
 
     const historyEntry = {
-      type: "create-reserve",
-      level: HistoryLevel.Expert,
-      timestamp: now,
-      subjectId: `reserve-progress-${reserveRecord.reserve_pub}`,
       detail: {
         requestedAmount: req.amount,
         reservePub: reserveRecord.reserve_pub,
-      }
+      },
+      level: HistoryLevel.Expert,
+      subjectId: `reserve-progress-${reserveRecord.reserve_pub}`,
+      timestamp: now,
+      type: "create-reserve",
     };
 
-    let exchangeInfo = await this.updateExchangeFromUrl(req.exchange);
-    let {isAudited, isTrusted} = await this.getExchangeTrust(exchangeInfo);
+    const exchangeInfo = await this.updateExchangeFromUrl(req.exchange);
+    const {isAudited, isTrusted} = await this.getExchangeTrust(exchangeInfo);
     let currencyRecord = await this.q().get(Stores.currencies, 
exchangeInfo.currency);
     if (!currencyRecord) {
       currencyRecord = {
-        name: exchangeInfo.currency,
-        fractionalDigits: 2,
-        exchanges: [],
         auditors: [],
-      }
+        exchanges: [],
+        fractionalDigits: 2,
+        name: exchangeInfo.currency,
+      };
     }
 
     if (!isAudited && !isTrusted) {
@@ -1081,7 +1098,7 @@ export class Wallet {
               .put(Stores.history, historyEntry)
               .finish();
 
-    let r: CreateReserveResponse = {
+    const r: CreateReserveResponse = {
       exchange: canonExchange,
       reservePub: keypair.pub,
     };
@@ -1099,8 +1116,8 @@ export class Wallet {
    * an unconfirmed reserve should be hidden.
    */
   async confirmReserve(req: ConfirmReserveRequest): Promise<void> {
-    const now = (new Date).getTime();
-    let reserve: ReserveRecord|undefined = await (
+    const now = (new Date()).getTime();
+    const reserve: ReserveRecord|undefined = await (
       this.q().get<ReserveRecord>(Stores.reserves,
                                   req.reservePub));
     if (!reserve) {
@@ -1109,15 +1126,15 @@ export class Wallet {
     }
     console.log("reserve confirmed");
     const historyEntry: HistoryRecord = {
-      type: "confirm-reserve",
-      timestamp: now,
-      subjectId: `reserve-progress-${reserve.reserve_pub}`,
       detail: {
         exchangeBaseUrl: reserve.exchange_base_url,
-        reservePub: req.reservePub,
         requestedAmount: reserve.requested_amount,
+        reservePub: req.reservePub,
       },
       level: HistoryLevel.User,
+      subjectId: `reserve-progress-${reserve.reserve_pub}`,
+      timestamp: now,
+      type: "confirm-reserve",
     };
     reserve.confirmed = true;
     await this.q()
@@ -1131,40 +1148,40 @@ export class Wallet {
 
 
   private async withdrawExecute(pc: PreCoinRecord): Promise<CoinRecord> {
-    let reserve = await this.q().get<ReserveRecord>(Stores.reserves,
+    const reserve = await this.q().get<ReserveRecord>(Stores.reserves,
                                                     pc.reservePub);
 
     if (!reserve) {
       throw Error("db inconsistent");
     }
 
-    let wd: any = {};
+    const wd: any = {};
     wd.denom_pub = pc.denomPub;
     wd.reserve_pub = pc.reservePub;
     wd.reserve_sig = pc.withdrawSig;
     wd.coin_ev = pc.coinEv;
-    let reqUrl = (new 
URI("reserve/withdraw")).absoluteTo(reserve.exchange_base_url);
-    let resp = await this.http.postJson(reqUrl.href(), wd);
+    const reqUrl = (new 
URI("reserve/withdraw")).absoluteTo(reserve.exchange_base_url);
+    const resp = await this.http.postJson(reqUrl.href(), wd);
 
-    if (resp.status != 200) {
+    if (resp.status !== 200) {
       throw new RequestException({
         hint: "Withdrawal failed",
-        status: resp.status
+        status: resp.status,
       });
     }
-    let r = JSON.parse(resp.responseText);
-    let denomSig = await this.cryptoApi.rsaUnblind(r.ev_sig,
+    const r = JSON.parse(resp.responseText);
+    const denomSig = await this.cryptoApi.rsaUnblind(r.ev_sig,
                                                    pc.blindingKey,
                                                    pc.denomPub);
-    let coin: CoinRecord = {
-      reservePub: pc.reservePub,
-      coinPub: pc.coinPub,
-      coinPriv: pc.coinPriv,
-      denomPub: pc.denomPub,
-      denomSig: denomSig,
+    const coin: CoinRecord = {
       blindingKey: pc.blindingKey,
+      coinPriv: pc.coinPriv,
+      coinPub: pc.coinPub,
       currentAmount: pc.coinValue,
+      denomPub: pc.denomPub,
+      denomSig,
       exchangeBaseUrl: pc.exchangeBaseUrl,
+      reservePub: pc.reservePub,
       status: CoinStatus.Fresh,
     };
     return coin;
@@ -1179,25 +1196,24 @@ export class Wallet {
     if (!reserve.current_amount) {
       throw Error("can't withdraw when amount is unknown");
     }
-    let currentAmount = reserve.current_amount;
-    if (!currentAmount) {
+    const withdrawAmount = reserve.current_amount;
+    if (!withdrawAmount) {
       throw Error("can't withdraw when amount is unknown");
     }
-    let denomsForWithdraw = await 
this.getVerifiedWithdrawDenomList(reserve.exchange_base_url,
-                                                                    
currentAmount);
+    const denomsForWithdraw = await 
this.getVerifiedWithdrawDenomList(reserve.exchange_base_url, withdrawAmount);
 
     console.log(`withdrawing ${denomsForWithdraw.length} coins`);
 
-    let ps = denomsForWithdraw.map(async(denom) => {
+    const ps = denomsForWithdraw.map(async(denom) => {
       function mutateReserve(r: ReserveRecord): ReserveRecord {
-        let currentAmount = r.current_amount;
+        const currentAmount = r.current_amount;
         if (!currentAmount) {
           throw Error("can't withdraw when amount is unknown");
         }
         r.precoin_amount = Amounts.add(r.precoin_amount,
                                        denom.value,
                                        denom.feeWithdraw).amount;
-        let result = Amounts.sub(currentAmount,
+        const result = Amounts.sub(currentAmount,
                                  denom.value,
                                  denom.feeWithdraw);
         if (result.saturated) {
@@ -1212,7 +1228,7 @@ export class Wallet {
         return r;
       }
 
-      let preCoin = await this.cryptoApi
+      const preCoin = await this.cryptoApi
                               .createPreCoin(denom, reserve);
       await this.q()
                 .put(Stores.precoins, preCoin)
@@ -1230,34 +1246,34 @@ export class Wallet {
    * by quering the reserve's exchange.
    */
   private async updateReserve(reservePub: string): Promise<ReserveRecord> {
-    let reserve = await this.q()
+    const reserve = await this.q()
                             .get<ReserveRecord>(Stores.reserves, reservePub);
     if (!reserve) {
       throw Error("reserve not in db");
     }
-    let reqUrl = new 
URI("reserve/status").absoluteTo(reserve.exchange_base_url);
-    reqUrl.query({'reserve_pub': reservePub});
-    let resp = await this.http.get(reqUrl.href());
-    if (resp.status != 200) {
+    const reqUrl = new 
URI("reserve/status").absoluteTo(reserve.exchange_base_url);
+    reqUrl.query({reserve_pub: reservePub});
+    const resp = await this.http.get(reqUrl.href());
+    if (resp.status !== 200) {
       throw Error();
     }
-    let reserveInfo = JSON.parse(resp.responseText);
+    const reserveInfo = JSON.parse(resp.responseText);
     if (!reserveInfo) {
       throw Error();
     }
-    let oldAmount = reserve.current_amount;
-    let newAmount = reserveInfo.balance;
+    const oldAmount = reserve.current_amount;
+    const newAmount = reserveInfo.balance;
     reserve.current_amount = reserveInfo.balance;
-    let historyEntry = {
-      type: "reserve-update",
-      timestamp: (new Date).getTime(),
-      subjectId: `reserve-progress-${reserve.reserve_pub}`,
+    const historyEntry = {
       detail: {
-        reservePub,
-        requestedAmount: reserve.requested_amount,
+        newAmount,
         oldAmount,
-        newAmount
-      }
+        requestedAmount: reserve.requested_amount,
+        reservePub,
+      },
+      subjectId: `reserve-progress-${reserve.reserve_pub}`,
+      timestamp: (new Date()).getTime(),
+      type: "reserve-update",
     };
     await this.q()
               .put(Stores.reserves, reserve)
@@ -1272,16 +1288,16 @@ export class Wallet {
    */
   async getWireInfo(exchangeBaseUrl: string): Promise<WireInfo> {
     exchangeBaseUrl = canonicalizeBaseUrl(exchangeBaseUrl);
-    let reqUrl = new URI("wire").absoluteTo(exchangeBaseUrl);
-    let resp = await this.http.get(reqUrl.href());
+    const reqUrl = new URI("wire").absoluteTo(exchangeBaseUrl);
+    const resp = await this.http.get(reqUrl.href());
 
-    if (resp.status != 200) {
+    if (resp.status !== 200) {
       throw Error("/wire request failed");
     }
 
-    let wiJson = JSON.parse(resp.responseText);
+    const wiJson = JSON.parse(resp.responseText);
     if (!wiJson) {
-      throw Error("/wire response malformed")
+      throw Error("/wire response malformed");
     }
     return wiJson;
   }
@@ -1290,7 +1306,7 @@ export class Wallet {
     return (
       this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex,
                          exchangeBaseUrl)
-          .filter((d) => d.status == DenominationStatus.Unverified || d.status 
== DenominationStatus.VerifiedGood)
+          .filter((d) => d.status === DenominationStatus.Unverified || 
d.status === DenominationStatus.VerifiedGood)
           .toArray()
     );
   }
@@ -1312,7 +1328,7 @@ export class Wallet {
     const possibleDenoms = await (
       this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex,
                          exchange.baseUrl)
-          .filter((d) => d.status == DenominationStatus.Unverified || d.status 
== DenominationStatus.VerifiedGood)
+          .filter((d) => d.status === DenominationStatus.Unverified || 
d.status === DenominationStatus.VerifiedGood)
           .toArray()
     );
 
@@ -1323,12 +1339,12 @@ export class Wallet {
 
     do {
       allValid = true;
-      let nextPossibleDenoms = [];
+      const nextPossibleDenoms = [];
       selectedDenoms = getWithdrawDenomList(amount, possibleDenoms);
-      for (let denom of selectedDenoms || []) {
-        if (denom.status == DenominationStatus.Unverified) {
+      for (const denom of selectedDenoms || []) {
+        if (denom.status === DenominationStatus.Unverified) {
           console.log(`verifying denom ${denom.denomPub.substr(0, 15)}`);
-          let valid = await this.cryptoApi.isValidDenom(denom,
+          const valid = await this.cryptoApi.isValidDenom(denom,
                                                         
exchange.masterPublicKey);
           if (!valid) {
             denom.status = DenominationStatus.VerifiedBad;
@@ -1349,24 +1365,23 @@ export class Wallet {
   }
 
 
-
   /**
    * Check if and how an exchange is trusted and/or audited.
    */
   async getExchangeTrust(exchangeInfo: ExchangeRecord): Promise<{isTrusted: 
boolean, isAudited: boolean}> {
     let isTrusted = false;
     let isAudited = false;
-    let currencyRecord = await this.q().get(Stores.currencies, 
exchangeInfo.currency);
+    const currencyRecord = await this.q().get(Stores.currencies, 
exchangeInfo.currency);
     if (currencyRecord) {
-      for (let trustedExchange of currencyRecord.exchanges) {
-        if (trustedExchange.baseUrl == exchangeInfo.baseUrl) {
+      for (const trustedExchange of currencyRecord.exchanges) {
+        if (trustedExchange.baseUrl === exchangeInfo.baseUrl) {
           isTrusted = true;
           break;
         }
       }
-      for (let trustedAuditor of currencyRecord.auditors) {
-        for (let exchangeAuditor of exchangeInfo.auditors) {
-          if (trustedAuditor.baseUrl == exchangeAuditor.url) {
+      for (const trustedAuditor of currencyRecord.auditors) {
+        for (const exchangeAuditor of exchangeInfo.auditors) {
+          if (trustedAuditor.baseUrl === exchangeAuditor.url) {
             isAudited = true;
             break;
           }
@@ -1378,47 +1393,47 @@ export class Wallet {
 
   async getReserveCreationInfo(baseUrl: string,
                                amount: AmountJson): 
Promise<ReserveCreationInfo> {
-    let exchangeInfo = await this.updateExchangeFromUrl(baseUrl);
+    const exchangeInfo = await this.updateExchangeFromUrl(baseUrl);
 
-    let selectedDenoms = await this.getVerifiedWithdrawDenomList(baseUrl,
+    const selectedDenoms = await this.getVerifiedWithdrawDenomList(baseUrl,
                                                                  amount);
     let acc = Amounts.getZero(amount.currency);
-    for (let d of selectedDenoms) {
+    for (const d of selectedDenoms) {
       acc = Amounts.add(acc, d.feeWithdraw).amount;
     }
-    let actualCoinCost = selectedDenoms
+    const actualCoinCost = selectedDenoms
       .map((d: DenominationRecord) => Amounts.add(d.value,
                                                   d.feeWithdraw).amount)
       .reduce((a, b) => Amounts.add(a, b).amount);
 
-    let wireInfo = await this.getWireInfo(baseUrl);
+    const wireInfo = await this.getWireInfo(baseUrl);
 
-    let wireFees = await this.q().get(Stores.exchangeWireFees, baseUrl);
+    const wireFees = await this.q().get(Stores.exchangeWireFees, baseUrl);
     if (!wireFees) {
       // should never happen unless DB is inconsistent
       throw Error(`no wire fees found for exchange ${baseUrl}`);
     }
 
-    let {isTrusted, isAudited} = await this.getExchangeTrust(exchangeInfo);
+    const {isTrusted, isAudited} = await this.getExchangeTrust(exchangeInfo);
 
-    let earliestDepositExpiration = Infinity;;
-    for (let denom of selectedDenoms) {
-      let expireDeposit = getTalerStampSec(denom.stampExpireDeposit)!;
+    let earliestDepositExpiration = Infinity;
+    for (const denom of selectedDenoms) {
+      const expireDeposit = getTalerStampSec(denom.stampExpireDeposit)!;
       if (expireDeposit < earliestDepositExpiration) {
         earliestDepositExpiration = expireDeposit;
       }
     }
 
-    let ret: ReserveCreationInfo = {
+    const ret: ReserveCreationInfo = {
+      earliestDepositExpiration,
       exchangeInfo,
-      selectedDenoms,
-      wireInfo,
-      wireFees,
       isAudited,
       isTrusted,
-      withdrawFee: acc,
-      earliestDepositExpiration,
       overhead: Amounts.sub(amount, actualCoinCost).amount,
+      selectedDenoms,
+      wireFees,
+      wireInfo,
+      withdrawFee: acc,
     };
     return ret;
   }
@@ -1431,24 +1446,24 @@ export class Wallet {
    */
   async updateExchangeFromUrl(baseUrl: string): Promise<ExchangeRecord> {
     baseUrl = canonicalizeBaseUrl(baseUrl);
-    let keysUrl = new URI("keys").absoluteTo(baseUrl);
-    let wireUrl = new URI("wire").absoluteTo(baseUrl);
-    let keysResp = await this.http.get(keysUrl.href());
-    if (keysResp.status != 200) {
+    const keysUrl = new URI("keys").absoluteTo(baseUrl);
+    const wireUrl = new URI("wire").absoluteTo(baseUrl);
+    const keysResp = await this.http.get(keysUrl.href());
+    if (keysResp.status !== 200) {
       throw Error("/keys request failed");
     }
-    let wireResp = await this.http.get(wireUrl.href());
-    if (wireResp.status != 200) {
+    const wireResp = await this.http.get(wireUrl.href());
+    if (wireResp.status !== 200) {
       throw Error("/wire request failed");
     }
-    let exchangeKeysJson = KeysJson.checked(JSON.parse(keysResp.responseText));
-    let wireRespJson = JSON.parse(wireResp.responseText);
+    const exchangeKeysJson = 
KeysJson.checked(JSON.parse(keysResp.responseText));
+    const wireRespJson = JSON.parse(wireResp.responseText);
     if (typeof wireRespJson !== "object") {
       throw Error("/wire response is not an object");
     }
     console.log("exchange wire", wireRespJson);
-    let wireMethodDetails: WireDetailJson[] = [];
-    for (let methodName in wireRespJson) {
+    const wireMethodDetails: WireDetailJson[] = [];
+    for (const methodName in wireRespJson) {
       wireMethodDetails.push(WireDetailJson.checked(wireRespJson[methodName]));
     }
     return this.updateExchangeFromJson(baseUrl, exchangeKeysJson, 
wireMethodDetails);
@@ -1456,12 +1471,12 @@ export class Wallet {
 
 
   private async suspendCoins(exchangeInfo: ExchangeRecord): Promise<void> {
-    let suspendedCoins = await (
+    const resultSuspendedCoins = await (
       this.q()
           .iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeInfo.baseUrl)
           .indexJoinLeft(Stores.denominations.exchangeBaseUrlIndex,
                          (e) => e.exchangeBaseUrl)
-          .reduce((cd: JoinLeftResult<CoinRecord,DenominationRecord>,
+          .reduce((cd: JoinLeftResult<CoinRecord, DenominationRecord>,
                    suspendedCoins: CoinRecord[]) => {
             if ((!cd.right) || (!cd.right.isOffered)) {
               return Array.prototype.concat(suspendedCoins, [cd.left]);
@@ -1469,8 +1484,8 @@ export class Wallet {
             return Array.prototype.concat(suspendedCoins);
           }, []));
 
-    let q = this.q();
-    suspendedCoins.map((c) => {
+    const q = this.q();
+    resultSuspendedCoins.map((c) => {
       console.log("suspending coin", c);
       c.suspended = true;
       q.put(Stores.coins, c);
@@ -1489,7 +1504,7 @@ export class Wallet {
       throw Error("invalid update time");
     }
 
-    if (exchangeKeysJson.denoms.length == 0) {
+    if (exchangeKeysJson.denoms.length === 0) {
       throw Error("exchange doesn't offer any denominations");
     }
 
@@ -1499,24 +1514,24 @@ export class Wallet {
 
     if (!r) {
       exchangeInfo = {
+        auditors: exchangeKeysJson.auditors,
         baseUrl,
+        currency: exchangeKeysJson.denoms[0].value.currency,
         lastUpdateTime: updateTimeSec,
         masterPublicKey: exchangeKeysJson.master_public_key,
-        auditors: exchangeKeysJson.auditors,
-        currency: exchangeKeysJson.denoms[0].value.currency,
       };
       console.log("making fresh exchange");
     } else {
       if (updateTimeSec < r.lastUpdateTime) {
         console.log("outdated /keys, not updating");
-        return r
+        return r;
       }
       exchangeInfo = r;
       exchangeInfo.lastUpdateTime = updateTimeSec;
       console.log("updating old exchange");
     }
 
-    let updatedExchangeInfo = await this.updateExchangeInfo(exchangeInfo,
+    const updatedExchangeInfo = await this.updateExchangeInfo(exchangeInfo,
                                                             exchangeKeysJson);
     await this.suspendCoins(updatedExchangeInfo);
 
@@ -1532,37 +1547,37 @@ export class Wallet {
       };
     }
 
-    for (let detail of wireMethodDetails) {
+    for (const detail of wireMethodDetails) {
       let latestFeeStamp = 0;
-      let fees = oldWireFees.feesForType[detail.type] || [];
+      const fees = oldWireFees.feesForType[detail.type] || [];
       oldWireFees.feesForType[detail.type] = fees;
-      for (let oldFee of fees) {
+      for (const oldFee of fees) {
         if (oldFee.endStamp > latestFeeStamp) {
           latestFeeStamp = oldFee.endStamp;
         }
       }
-      for (let fee of detail.fees) {
-        let start = getTalerStampSec(fee.start_date);
-        if (start == null) {
+      for (const fee of detail.fees) {
+        const start = getTalerStampSec(fee.start_date);
+        if (start === null) {
           console.error("invalid start stamp in fee", fee);
           continue;
         }
         if (start < latestFeeStamp) {
           continue;
         }
-        let end = getTalerStampSec(fee.end_date);
-        if (end == null) {
+        const end = getTalerStampSec(fee.end_date);
+        if (end === null) {
           console.error("invalid end stamp in fee", fee);
           continue;
         }
-        let wf: WireFee = {
-          wireFee: fee.wire_fee,
+        const wf: WireFee = {
           closingFee: fee.closing_fee,
+          endStamp: end,
           sig: fee.sig,
           startStamp: start,
-          endStamp: end,
-        }
-        let valid: boolean = await this.cryptoApi.isValidWireFee(detail.type, 
wf, exchangeInfo.masterPublicKey);
+          wireFee: fee.wire_fee,
+        };
+        const valid: boolean = await 
this.cryptoApi.isValidWireFee(detail.type, wf, exchangeInfo.masterPublicKey);
         if (!valid) {
           console.error("fee signature invalid", fee);
           throw Error("fee signature invalid");
@@ -1574,14 +1589,14 @@ export class Wallet {
     await this.q().put(Stores.exchangeWireFees, oldWireFees);
 
     if (exchangeKeysJson.payback) {
-      for (let payback of exchangeKeysJson.payback) {
-        let denom = await 
this.q().getIndexed(Stores.denominations.denomPubHashIndex, 
payback.h_denom_pub);
+      for (const payback of exchangeKeysJson.payback) {
+        const denom = await 
this.q().getIndexed(Stores.denominations.denomPubHashIndex, 
payback.h_denom_pub);
         if (!denom) {
           continue;
         }
         console.log(`cashing back denom`, denom);
-        let coins = await this.q().iterIndex(Stores.coins.denomPubIndex, 
denom.denomPub).toArray();
-        for (let coin of coins) {
+        const coins = await this.q().iterIndex(Stores.coins.denomPubIndex, 
denom.denomPub).toArray();
+        for (const coin of coins) {
           this.payback(coin.coinPub);
         }
       }
@@ -1593,7 +1608,7 @@ export class Wallet {
 
   private async updateExchangeInfo(exchangeInfo: ExchangeRecord,
                                    newKeys: KeysJson): Promise<ExchangeRecord> 
{
-    if (exchangeInfo.masterPublicKey != newKeys.master_public_key) {
+    if (exchangeInfo.masterPublicKey !== newKeys.master_public_key) {
       throw Error("public keys do not match");
     }
 
@@ -1608,17 +1623,17 @@ export class Wallet {
     const newDenoms: typeof existingDenoms = {};
     const newAndUnseenDenoms: typeof existingDenoms = {};
 
-    for (let d of newKeys.denoms) {
-      let dr = await this.denominationRecordFromKeys(exchangeInfo.baseUrl, d);
+    for (const d of newKeys.denoms) {
+      const dr = await this.denominationRecordFromKeys(exchangeInfo.baseUrl, 
d);
       if (!(d.denom_pub in existingDenoms)) {
         newAndUnseenDenoms[dr.denomPub] = dr;
       }
       newDenoms[dr.denomPub] = dr;
     }
 
-    for (let oldDenomPub in existingDenoms) {
+    for (const oldDenomPub in existingDenoms) {
       if (!(oldDenomPub in newDenoms)) {
-        let d = existingDenoms[oldDenomPub];
+        const d = existingDenoms[oldDenomPub];
         d.isOffered = false;
       }
     }
@@ -1640,13 +1655,13 @@ export class Wallet {
   async getBalances(): Promise<WalletBalance> {
     function ensureEntry(balance: WalletBalance, currency: string) {
       let entry: WalletBalanceEntry|undefined = balance[currency];
-      let z = Amounts.getZero(currency);
+      const z = Amounts.getZero(currency);
       if (!entry) {
         balance[currency] = entry = {
           available: z,
+          paybackAmount: z,
           pendingIncoming: z,
           pendingPayment: z,
-          paybackAmount: z,
         };
       }
       return entry;
@@ -1656,11 +1671,11 @@ export class Wallet {
       if (c.suspended) {
         return balance;
       }
-      if (!(c.status == CoinStatus.Dirty || c.status == CoinStatus.Fresh)) {
+      if (!(c.status === CoinStatus.Dirty || c.status === CoinStatus.Fresh)) {
         return balance;
       }
-      let currency = c.currentAmount.currency;
-      let entry = ensureEntry(balance, currency);
+      const currency = c.currentAmount.currency;
+      const entry = ensureEntry(balance, currency);
       entry.available = Amounts.add(entry.available, c.currentAmount).amount;
       return balance;
     }
@@ -1669,7 +1684,7 @@ export class Wallet {
       if (!r.confirmed) {
         return balance;
       }
-      let entry = ensureEntry(balance, r.requested_amount.currency);
+      const entry = ensureEntry(balance, r.requested_amount.currency);
       let amount = r.current_amount;
       if (!amount) {
         amount = r.requested_amount;
@@ -1686,7 +1701,7 @@ export class Wallet {
       if (!r.hasPayback) {
         return balance;
       }
-      let entry = ensureEntry(balance, r.requested_amount.currency);
+      const entry = ensureEntry(balance, r.requested_amount.currency);
       if (Amounts.cmp(smallestWithdraw[r.exchange_base_url], 
r.current_amount!) < 0) {
         entry.paybackAmount = Amounts.add(entry.paybackAmount, 
r.current_amount!).amount;
       }
@@ -1700,7 +1715,7 @@ export class Wallet {
       if (r.finished) {
         return balance;
       }
-      let entry = ensureEntry(balance, r.valueWithFee.currency);
+      const entry = ensureEntry(balance, r.valueWithFee.currency);
       entry.pendingIncoming = Amounts.add(entry.pendingIncoming,
                                           r.valueOutput).amount;
 
@@ -1711,7 +1726,7 @@ export class Wallet {
       if (t.finished) {
         return balance;
       }
-      let entry = ensureEntry(balance, t.contract.amount.currency);
+      const entry = ensureEntry(balance, t.contract.amount.currency);
       entry.pendingPayment = Amounts.add(entry.pendingPayment,
                                          t.contract.amount).amount;
 
@@ -1721,7 +1736,7 @@ export class Wallet {
     function collectSmallestWithdraw(e: JoinResult<ExchangeRecord, 
DenominationRecord>,
                                      sw: any) {
       let min = sw[e.left.baseUrl];
-      let v = Amounts.add(e.right.value, e.right.feeWithdraw).amount;
+      const v = Amounts.add(e.right.value, e.right.feeWithdraw).amount;
       if (!min) {
         min = v;
       } else if (Amounts.cmp(v, min) < 0) {
@@ -1731,7 +1746,7 @@ export class Wallet {
       return sw;
     }
 
-    let balance = {};
+    const balance = {};
     // Mapping from exchange pub to smallest
     // possible amount we can withdraw
     let smallestWithdraw: {[baseUrl: string]: AmountJson} = {};
@@ -1742,7 +1757,7 @@ export class Wallet {
                                              (x) => x.baseUrl)
                                   .reduce(collectSmallestWithdraw, {}));
 
-    let tx = this.q();
+    const tx = this.q();
     tx.iter(Stores.coins)
       .reduce(collectBalances, balance);
     tx.iter(Stores.refresh)
@@ -1760,52 +1775,52 @@ export class Wallet {
 
 
   async createRefreshSession(oldCoinPub: string): 
Promise<RefreshSessionRecord|undefined> {
-    let coin = await this.q().get<CoinRecord>(Stores.coins, oldCoinPub);
+    const coin = await this.q().get<CoinRecord>(Stores.coins, oldCoinPub);
 
     if (!coin) {
       throw Error("coin not found");
     }
 
-    if (coin.currentAmount.value == 0 && coin.currentAmount.fraction == 0) {
+    if (coin.currentAmount.value === 0 && coin.currentAmount.fraction === 0) {
       return undefined;
     }
 
-    let exchange = await this.updateExchangeFromUrl(coin.exchangeBaseUrl);
+    const exchange = await this.updateExchangeFromUrl(coin.exchangeBaseUrl);
 
     if (!exchange) {
       throw Error("db inconsistent");
     }
 
-    let oldDenom = await this.q().get(Stores.denominations,
+    const oldDenom = await this.q().get(Stores.denominations,
                                       [exchange.baseUrl, coin.denomPub]);
 
     if (!oldDenom) {
       throw Error("db inconsistent");
     }
 
-    let availableDenoms: DenominationRecord[] = await (
+    const availableDenoms: DenominationRecord[] = await (
       this.q()
           .iterIndex(Stores.denominations.exchangeBaseUrlIndex,
                      exchange.baseUrl)
           .toArray()
     );
 
-    let availableAmount = Amounts.sub(coin.currentAmount,
+    const availableAmount = Amounts.sub(coin.currentAmount,
                                       oldDenom.feeRefresh).amount;
 
-    let newCoinDenoms = getWithdrawDenomList(availableAmount,
+    const newCoinDenoms = getWithdrawDenomList(availableAmount,
                                              availableDenoms);
 
     console.log("refreshing coin", coin);
     console.log("refreshing into", newCoinDenoms);
 
-    if (newCoinDenoms.length == 0) {
+    if (newCoinDenoms.length === 0) {
       console.log(`not refreshing, available amount 
${amountToPretty(availableAmount)} too small`);
       return undefined;
     }
 
 
-    let refreshSession: RefreshSessionRecord = await (
+    const refreshSession: RefreshSessionRecord = await (
       this.cryptoApi.createRefreshSession(exchange.baseUrl,
                                           3,
                                           coin,
@@ -1813,7 +1828,7 @@ export class Wallet {
                                           oldDenom.feeRefresh));
 
     function mutateCoin(c: CoinRecord): CoinRecord {
-      let r = Amounts.sub(c.currentAmount,
+      const r = Amounts.sub(c.currentAmount,
                           refreshSession.valueWithFee);
       if (r.saturated) {
         // Something else must have written the coin value
@@ -1837,7 +1852,7 @@ export class Wallet {
 
   async refresh(oldCoinPub: string): Promise<void> {
     let refreshSession: RefreshSessionRecord|undefined;
-    let oldSession = await this.q().get(Stores.refresh, oldCoinPub);
+    const oldSession = await this.q().get(Stores.refresh, oldCoinPub);
     if (oldSession) {
       console.log("got old session for", oldCoinPub);
       console.log(oldSession);
@@ -1858,9 +1873,9 @@ export class Wallet {
       return;
     }
     if (typeof refreshSession.norevealIndex !== "number") {
-      let coinPub = refreshSession.meltCoinPub;
+      const coinPub = refreshSession.meltCoinPub;
       await this.refreshMelt(refreshSession);
-      let r = await this.q().get<RefreshSessionRecord>(Stores.refresh, 
coinPub);
+      const r = await this.q().get<RefreshSessionRecord>(Stores.refresh, 
coinPub);
       if (!r) {
         throw Error("refresh session does not exist anymore");
       }
@@ -1872,53 +1887,53 @@ export class Wallet {
 
 
   async refreshMelt(refreshSession: RefreshSessionRecord): Promise<void> {
-    if (refreshSession.norevealIndex != undefined) {
+    if (refreshSession.norevealIndex !== undefined) {
       console.error("won't melt again");
       return;
     }
 
-    let coin = await this.q().get<CoinRecord>(Stores.coins,
+    const coin = await this.q().get<CoinRecord>(Stores.coins,
                                               refreshSession.meltCoinPub);
     if (!coin) {
       console.error("can't melt coin, it does not exist");
       return;
     }
 
-    let reqUrl = new 
URI("refresh/melt").absoluteTo(refreshSession.exchangeBaseUrl);
-    let meltCoin = {
+    const reqUrl = new 
URI("refresh/melt").absoluteTo(refreshSession.exchangeBaseUrl);
+    const meltCoin = {
       coin_pub: coin.coinPub,
+      confirm_sig: refreshSession.confirmSig,
       denom_pub: coin.denomPub,
       denom_sig: coin.denomSig,
-      confirm_sig: refreshSession.confirmSig,
       value_with_fee: refreshSession.valueWithFee,
     };
-    let coinEvs = refreshSession.preCoinsForGammas.map((x) => x.map((y) => 
y.coinEv));
-    let req = {
-      "new_denoms": refreshSession.newDenoms,
-      "melt_coin": meltCoin,
-      "transfer_pubs": refreshSession.transferPubs,
-      "coin_evs": coinEvs,
+    const coinEvs = refreshSession.preCoinsForGammas.map((x) => x.map((y) => 
y.coinEv));
+    const req = {
+      coin_evs: coinEvs,
+      melt_coin: meltCoin,
+      new_denoms: refreshSession.newDenoms,
+      transfer_pubs: refreshSession.transferPubs,
     };
     console.log("melt request:", req);
-    let resp = await this.http.postJson(reqUrl.href(), req);
+    const resp = await this.http.postJson(reqUrl.href(), req);
 
     console.log("melt request:", req);
     console.log("melt response:", resp.responseText);
 
-    if (resp.status != 200) {
+    if (resp.status !== 200) {
       console.error(resp.responseText);
       throw Error("refresh failed");
     }
 
-    let respJson = JSON.parse(resp.responseText);
+    const respJson = JSON.parse(resp.responseText);
 
     if (!respJson) {
       throw Error("exchange responded with garbage");
     }
 
-    let norevealIndex = respJson.noreveal_index;
+    const norevealIndex = respJson.noreveal_index;
 
-    if (typeof norevealIndex != "number") {
+    if (typeof norevealIndex !== "number") {
       throw Error("invalid response");
     }
 
@@ -1929,71 +1944,70 @@ export class Wallet {
 
 
   async refreshReveal(refreshSession: RefreshSessionRecord): Promise<void> {
-    let norevealIndex = refreshSession.norevealIndex;
-    if (norevealIndex == undefined) {
+    const norevealIndex = refreshSession.norevealIndex;
+    if (norevealIndex === undefined) {
       throw Error("can't reveal without melting first");
     }
-    let privs = Array.from(refreshSession.transferPrivs);
+    const privs = Array.from(refreshSession.transferPrivs);
     privs.splice(norevealIndex, 1);
 
-    let req = {
-      "session_hash": refreshSession.hash,
-      "transfer_privs": privs,
+    const req = {
+      session_hash: refreshSession.hash,
+      transfer_privs: privs,
     };
 
-    let reqUrl = new URI("refresh/reveal")
-      .absoluteTo(refreshSession.exchangeBaseUrl);
+    const reqUrl = new URI("refresh/reveal") 
.absoluteTo(refreshSession.exchangeBaseUrl);
     console.log("reveal request:", req);
-    let resp = await this.http.postJson(reqUrl.href(), req);
+    const resp = await this.http.postJson(reqUrl.href(), req);
 
     console.log("session:", refreshSession);
     console.log("reveal response:", resp);
 
-    if (resp.status != 200) {
+    if (resp.status !== 200) {
       console.log("error:  /refresh/reveal returned status " + resp.status);
       return;
     }
 
-    let respJson = JSON.parse(resp.responseText);
+    const respJson = JSON.parse(resp.responseText);
 
     if (!respJson.ev_sigs || !Array.isArray(respJson.ev_sigs)) {
       console.log("/refresh/reveal did not contain ev_sigs");
     }
 
-    let exchange = await this.q().get<ExchangeRecord>(Stores.exchanges,
+    const exchange = await this.q().get<ExchangeRecord>(Stores.exchanges,
                                                       
refreshSession.exchangeBaseUrl);
     if (!exchange) {
       console.error(`exchange ${refreshSession.exchangeBaseUrl} not found`);
       return;
     }
 
-    let coins: CoinRecord[] = [];
+    const coins: CoinRecord[] = [];
 
     for (let i = 0; i < respJson.ev_sigs.length; i++) {
-      let denom = await (
+      const denom = await (
         this.q()
             .get(Stores.denominations,
                  [
                    refreshSession.exchangeBaseUrl,
-                   refreshSession.newDenoms[i]
+                   refreshSession.newDenoms[i],
                  ]));
       if (!denom) {
         console.error("denom not found");
         continue;
       }
-      let pc = 
refreshSession.preCoinsForGammas[refreshSession.norevealIndex!][i];
-      let denomSig = await 
this.cryptoApi.rsaUnblind(respJson.ev_sigs[i].ev_sig,
+      const pc = 
refreshSession.preCoinsForGammas[refreshSession.norevealIndex!][i];
+      const denomSig = await 
this.cryptoApi.rsaUnblind(respJson.ev_sigs[i].ev_sig,
                                                      pc.blindingKey,
                                                      denom.denomPub);
-      let coin: CoinRecord = {
-        reservePub: undefined,
+      const coin: CoinRecord = {
         blindingKey: pc.blindingKey,
-        coinPub: pc.publicKey,
         coinPriv: pc.privateKey,
-        denomPub: denom.denomPub,
-        denomSig: denomSig,
+        coinPub: pc.publicKey,
         currentAmount: denom.value,
+        denomPub: denom.denomPub,
+        denomSig,
         exchangeBaseUrl: refreshSession.exchangeBaseUrl,
+        reservePub: undefined,
         status: CoinStatus.Fresh,
       };
 
@@ -2018,7 +2032,7 @@ export class Wallet {
       return acc;
     }
 
-    let history = await (
+    const history = await (
       this.q()
           .iterIndex(Stores.history.timestampIndex)
           .reduce(collect, []));
@@ -2027,12 +2041,12 @@ export class Wallet {
   }
 
   async getDenoms(exchangeUrl: string): Promise<DenominationRecord[]> {
-    let denoms = await 
this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex, 
exchangeUrl).toArray();
+    const denoms = await 
this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex, 
exchangeUrl).toArray();
     return denoms;
   }
 
   async getOffer(offerId: number): Promise<any> {
-    let offer = await this.q() .get(Stores.offers, offerId);
+    const offer = await this.q() .get(Stores.offers, offerId);
     return offer;
   }
 
@@ -2089,7 +2103,7 @@ export class Wallet {
    * Store the private key in our DB, so we can prove ownership.
    */
   async generateNonce(): Promise<string> {
-    let {priv, pub} = await this.cryptoApi.createEddsaKeypair();
+    const {priv, pub} = await this.cryptoApi.createEddsaKeypair();
     await this.q()
               .put(Stores.nonces, {priv, pub})
               .finish();
@@ -2103,23 +2117,23 @@ export class Wallet {
 
   async paymentSucceeded(contractHash: string, merchantSig: string): 
Promise<any> {
     const doPaymentSucceeded = async() => {
-      let t = await this.q().get<TransactionRecord>(Stores.transactions,
+      const t = await this.q().get<TransactionRecord>(Stores.transactions,
                                                     contractHash);
       if (!t) {
         console.error("contract not found");
         return;
       }
-      let merchantPub = t.contract.merchant_pub;
-      let valid = this.cryptoApi.isValidPaymentSignature(merchantSig, 
contractHash, merchantPub);
+      const merchantPub = t.contract.merchant_pub;
+      const valid = this.cryptoApi.isValidPaymentSignature(merchantSig, 
contractHash, merchantPub);
       if (!valid) {
         console.error("merchant payment signature invalid");
         // FIXME: properly display error
         return;
       }
       t.finished = true;
-      let modifiedCoins: CoinRecord[] = [];
-      for (let pc of t.payReq.coins) {
-        let c = await this.q().get<CoinRecord>(Stores.coins, pc.coin_pub);
+      const modifiedCoins: CoinRecord[] = [];
+      for (const pc of t.payReq.coins) {
+        const c = await this.q().get<CoinRecord>(Stores.coins, pc.coin_pub);
         if (!c) {
           console.error("coin not found");
           return;
@@ -2132,7 +2146,7 @@ export class Wallet {
                 .putAll(Stores.coins, modifiedCoins)
                 .put(Stores.transactions, t)
                 .finish();
-      for (let c of t.payReq.coins) {
+      for (const c of t.payReq.coins) {
         this.refresh(c.coin_pub);
       }
     };
@@ -2145,11 +2159,11 @@ export class Wallet {
     if (!coin) {
       throw Error(`Coin ${coinPub} not found, can't request payback`);
     }
-    let reservePub = coin.reservePub;
+    const reservePub = coin.reservePub;
     if (!reservePub) {
       throw Error(`Can't request payback for a refreshed coin`);
     }
-    let reserve = await this.q().get(Stores.reserves, reservePub);
+    const reserve = await this.q().get(Stores.reserves, reservePub);
     if (!reserve) {
       throw Error(`Reserve of coin ${coinPub} not found`);
     }
@@ -2167,14 +2181,14 @@ export class Wallet {
     reserve.hasPayback = true;
     await this.q().put(Stores.coins, coin).put(Stores.reserves, reserve);
 
-    let paybackRequest = await this.cryptoApi.createPaybackRequest(coin);
-    let reqUrl = new URI("payback").absoluteTo(coin.exchangeBaseUrl);
-    let resp = await this.http.postJson(reqUrl.href(), paybackRequest);
-    if (resp.status != 200) {
+    const paybackRequest = await this.cryptoApi.createPaybackRequest(coin);
+    const reqUrl = new URI("payback").absoluteTo(coin.exchangeBaseUrl);
+    const resp = await this.http.postJson(reqUrl.href(), paybackRequest);
+    if (resp.status !== 200) {
       throw Error();
     }
-    let paybackConfirmation = 
PaybackConfirmation.checked(JSON.parse(resp.responseText));
-    if (paybackConfirmation.reserve_pub != coin.reservePub) {
+    const paybackConfirmation = 
PaybackConfirmation.checked(JSON.parse(resp.responseText));
+    if (paybackConfirmation.reserve_pub !== coin.reservePub) {
       throw Error(`Coin's reserve doesn't match reserve on payback`);
     }
     coin = await this.q().get(Stores.coins, coinPub);
@@ -2188,29 +2202,29 @@ export class Wallet {
 
 
   async denominationRecordFromKeys(exchangeBaseUrl: string, denomIn: 
Denomination): Promise<DenominationRecord> {
-    let denomPubHash = await this.cryptoApi.hashDenomPub(denomIn.denom_pub);
-    let d: DenominationRecord = {
-      denomPubHash,
+    const denomPubHash = await this.cryptoApi.hashDenomPub(denomIn.denom_pub);
+    const d: DenominationRecord = {
       denomPub: denomIn.denom_pub,
-      exchangeBaseUrl: exchangeBaseUrl,
+      denomPubHash,
+      exchangeBaseUrl,
       feeDeposit: denomIn.fee_deposit,
-      masterSig: denomIn.master_sig,
-      feeRefund: denomIn.fee_refund,
       feeRefresh: denomIn.fee_refresh,
+      feeRefund: denomIn.fee_refund,
       feeWithdraw: denomIn.fee_withdraw,
+      isOffered: true,
+      masterSig: denomIn.master_sig,
       stampExpireDeposit: denomIn.stamp_expire_deposit,
       stampExpireLegal: denomIn.stamp_expire_legal,
       stampExpireWithdraw: denomIn.stamp_expire_withdraw,
       stampStart: denomIn.stamp_start,
       status: DenominationStatus.Unverified,
-      isOffered: true,
       value: denomIn.value,
     };
     return d;
   }
 
   async withdrawPaybackReserve(reservePub: string): Promise<void> {
-    let reserve = await this.q().get(Stores.reserves, reservePub);
+    const reserve = await this.q().get(Stores.reserves, reservePub);
     if (!reserve) {
       throw Error(`Reserve ${reservePub} does not exist`);
     }
@@ -2220,7 +2234,7 @@ export class Wallet {
   }
 
   async getPaybackReserves(): Promise<ReserveRecord[]> {
-    return await this.q().iter(Stores.reserves).filter(r => 
r.hasPayback).toArray()
+    return await this.q().iter(Stores.reserves).filter((r) => 
r.hasPayback).toArray();
   }
 
 }
diff --git a/src/wxApi.ts b/src/wxApi.ts
index b74cb9eb..1f7d08fb 100644
--- a/src/wxApi.ts
+++ b/src/wxApi.ts
@@ -17,11 +17,12 @@
 import {
   AmountJson,
   CoinRecord,
+  CurrencyRecord,
+  DenominationRecord,
+  ExchangeRecord,
   PreCoinRecord,
   ReserveCreationInfo,
-  ExchangeRecord,
-  CurrencyRecord,
-  ReserveRecord, DenominationRecord
+  ReserveRecord,
 } from "./types";
 
 /**
@@ -31,13 +32,13 @@ import {
 
 
 export function getReserveCreationInfo(baseUrl: string,
-  amount: AmountJson): Promise<ReserveCreationInfo> {
-  let m = { type: "reserve-creation-info", detail: { baseUrl, amount } };
+                                       amount: AmountJson): 
Promise<ReserveCreationInfo> {
+  const m = { type: "reserve-creation-info", detail: { baseUrl, amount } };
   return new Promise<ReserveCreationInfo>((resolve, reject) => {
     chrome.runtime.sendMessage(m, (resp) => {
       if (resp.error) {
         console.error("error response", resp);
-        let e = Error("call to reserve-creation-info failed");
+        const e = Error("call to reserve-creation-info failed");
         (e as any).errorResponse = resp;
         reject(e);
         return;
diff --git a/src/wxBackend.ts b/src/wxBackend.ts
index 26020c7f..6b960157 100644
--- a/src/wxBackend.ts
+++ b/src/wxBackend.ts
@@ -24,6 +24,20 @@
 /**
  * Imports.
  */
+import { Checkable } from "./checkable";
+import { ChromeBadge } from "./chromeBadge";
+import { BrowserHttpLib } from "./http";
+import * as logging from "./logging";
+import {
+  Index,
+  Store,
+} from "./query";
+import {
+  AmountJson,
+  Contract,
+  Notifier,
+} from "./types";
+import URI = require("urijs");
 import {
   Badge,
   ConfirmReserveRequest,
@@ -32,19 +46,8 @@ import {
   Stores,
   Wallet,
 } from "./wallet";
-import {
-  AmountJson,
-  Contract,
-  Notifier,
-} from "./types";
-import MessageSender = chrome.runtime.MessageSender;
-import { ChromeBadge } from "./chromeBadge";
-import * as logging from "./logging";
-import { Store, Index } from "./query";
-import { BrowserHttpLib } from "./http";
-import { Checkable } from "./checkable";
 import Port = chrome.runtime.Port;
-import URI = require("urijs");
+import MessageSender = chrome.runtime.MessageSender;
 
 
 const DB_NAME = "taler";
@@ -60,32 +63,33 @@ const DB_VERSION = 17;
 type Handler = (detail: any, sender: MessageSender) => Promise<any>;
 
 function makeHandlers(db: IDBDatabase,
-  wallet: Wallet): { [msg: string]: Handler } {
+                      wallet: Wallet): { [msg: string]: Handler } {
   return {
-    ["balances"]: function (detail, sender) {
+    ["balances"]: (detail, sender) => {
       return wallet.getBalances();
     },
-    ["dump-db"]: function (detail, sender) {
+    ["dump-db"]: (detail, sender) => {
       return exportDb(db);
     },
-    ["import-db"]: function (detail, sender) {
+    ["import-db"]: (detail, sender) => {
       return importDb(db, detail.dump);
     },
-    ["get-tab-cookie"]: function (detail, sender) {
+    ["get-tab-cookie"]: (detail, sender) => {
       if (!sender || !sender.tab || !sender.tab.id) {
         return Promise.resolve();
       }
-      let id: number = sender.tab.id;
-      let info: any = <any> paymentRequestCookies[id];
+      const id: number = sender.tab.id;
+      const info: any = paymentRequestCookies[id] as any;
       delete paymentRequestCookies[id];
       return Promise.resolve(info);
     },
-    ["ping"]: function (detail, sender) {
+    ["ping"]: (detail, sender) => {
       return Promise.resolve();
     },
-    ["reset"]: function (detail, sender) {
+    ["reset"]: (detail, sender) => {
       if (db) {
-        let tx = db.transaction(Array.from(db.objectStoreNames), 'readwrite');
+        const tx = db.transaction(Array.from(db.objectStoreNames), 
"readwrite");
+        // tslint:disable-next-line:prefer-for-of
         for (let i = 0; i < db.objectStoreNames.length; i++) {
           tx.objectStore(db.objectStoreNames[i]).clear();
         }
@@ -97,15 +101,15 @@ function makeHandlers(db: IDBDatabase,
       // Response is synchronous
       return Promise.resolve({});
     },
-    ["create-reserve"]: function (detail, sender) {
+    ["create-reserve"]: (detail, sender) => {
       const d = {
-        exchange: detail.exchange,
         amount: detail.amount,
+        exchange: detail.exchange,
       };
       const req = CreateReserveRequest.checked(d);
       return wallet.createReserve(req);
     },
-    ["confirm-reserve"]: function (detail, sender) {
+    ["confirm-reserve"]: (detail, sender) => {
       // TODO: make it a checkable
       const d = {
         reservePub: detail.reservePub,
@@ -113,10 +117,10 @@ function makeHandlers(db: IDBDatabase,
       const req = ConfirmReserveRequest.checked(d);
       return wallet.confirmReserve(req);
     },
-    ["generate-nonce"]: function (detail, sender) {
+    ["generate-nonce"]: (detail, sender) => {
       return wallet.generateNonce();
     },
-    ["confirm-pay"]: function (detail, sender) {
+    ["confirm-pay"]: (detail, sender) => {
       let offer: OfferRecord;
       try {
         offer = OfferRecord.checked(detail.offer);
@@ -124,9 +128,9 @@ function makeHandlers(db: IDBDatabase,
         if (e instanceof Checkable.SchemaError) {
           console.error("schema error:", e.message);
           return Promise.resolve({
+            detail,
             error: "invalid contract",
             hint: e.message,
-            detail: detail,
           });
         } else {
           throw e;
@@ -135,7 +139,7 @@ function makeHandlers(db: IDBDatabase,
 
       return wallet.confirmPay(offer);
     },
-    ["check-pay"]: function (detail, sender) {
+    ["check-pay"]: (detail, sender) => {
       let offer: OfferRecord;
       try {
         offer = OfferRecord.checked(detail.offer);
@@ -143,9 +147,9 @@ function makeHandlers(db: IDBDatabase,
         if (e instanceof Checkable.SchemaError) {
           console.error("schema error:", e.message);
           return Promise.resolve({
+            detail,
             error: "invalid contract",
             hint: e.message,
-            detail: detail,
           });
         } else {
           throw e;
@@ -153,34 +157,34 @@ function makeHandlers(db: IDBDatabase,
       }
       return wallet.checkPay(offer);
     },
-    ["query-payment"]: function (detail: any, sender: MessageSender) {
+    ["query-payment"]: (detail: any, sender: MessageSender) => {
       if (sender.tab && sender.tab.id) {
         rateLimitCache[sender.tab.id]++;
         if (rateLimitCache[sender.tab.id] > 10) {
           console.warn("rate limit for query-payment exceeded");
-          let msg = {
+          const msg = {
             error: "rate limit exceeded for query-payment",
-            rateLimitExceeded: true,
             hint: "Check for redirect loops",
+            rateLimitExceeded: true,
           };
           return Promise.resolve(msg);
         }
       }
       return wallet.queryPayment(detail.url);
     },
-    ["exchange-info"]: function (detail) {
+    ["exchange-info"]: (detail) => {
       if (!detail.baseUrl) {
         return Promise.resolve({ error: "bad url" });
       }
       return wallet.updateExchangeFromUrl(detail.baseUrl);
     },
-    ["currency-info"]: function (detail) {
+    ["currency-info"]: (detail) => {
       if (!detail.name) {
         return Promise.resolve({ error: "name missing" });
       }
       return wallet.getCurrencyRecord(detail.name);
     },
-    ["hash-contract"]: function (detail) {
+    ["hash-contract"]: (detail) => {
       if (!detail.contract) {
         return Promise.resolve({ error: "contract missing" });
       }
@@ -188,91 +192,91 @@ function makeHandlers(db: IDBDatabase,
         return { hash };
       });
     },
-    ["put-history-entry"]: function (detail: any) {
+    ["put-history-entry"]: (detail: any) => {
       if (!detail.historyEntry) {
         return Promise.resolve({ error: "historyEntry missing" });
       }
       return wallet.putHistory(detail.historyEntry);
     },
-    ["save-offer"]: function (detail: any) {
-      let offer = detail.offer;
+    ["save-offer"]: (detail: any) => {
+      const offer = detail.offer;
       if (!offer) {
         return Promise.resolve({ error: "offer missing" });
       }
       console.log("handling safe-offer", detail);
       // FIXME:  fully migrate to new terminology
-      let checkedOffer = OfferRecord.checked(offer);
+      const checkedOffer = OfferRecord.checked(offer);
       return wallet.saveOffer(checkedOffer);
     },
-    ["reserve-creation-info"]: function (detail, sender) {
+    ["reserve-creation-info"]: (detail, sender) => {
       if (!detail.baseUrl || typeof detail.baseUrl !== "string") {
         return Promise.resolve({ error: "bad url" });
       }
-      let amount = AmountJson.checked(detail.amount);
+      const amount = AmountJson.checked(detail.amount);
       return wallet.getReserveCreationInfo(detail.baseUrl, amount);
     },
-    ["get-history"]: function (detail, sender) {
+    ["get-history"]: (detail, sender) => {
       // TODO: limit history length
       return wallet.getHistory();
     },
-    ["get-offer"]: function (detail, sender) {
+    ["get-offer"]: (detail, sender) => {
       return wallet.getOffer(detail.offerId);
     },
-    ["get-exchanges"]: function (detail, sender) {
+    ["get-exchanges"]: (detail, sender) => {
       return wallet.getExchanges();
     },
-    ["get-currencies"]: function (detail, sender) {
+    ["get-currencies"]: (detail, sender) => {
       return wallet.getCurrencies();
     },
-    ["update-currency"]: function (detail, sender) {
+    ["update-currency"]: (detail, sender) => {
       return wallet.updateCurrency(detail.currencyRecord);
     },
-    ["get-reserves"]: function (detail, sender) {
+    ["get-reserves"]: (detail, sender) => {
       if (typeof detail.exchangeBaseUrl !== "string") {
         return Promise.reject(Error("exchangeBaseUrl missing"));
       }
       return wallet.getReserves(detail.exchangeBaseUrl);
     },
-    ["get-payback-reserves"]: function (detail, sender) {
+    ["get-payback-reserves"]: (detail, sender) => {
       return wallet.getPaybackReserves();
     },
-    ["withdraw-payback-reserve"]: function (detail, sender) {
+    ["withdraw-payback-reserve"]: (detail, sender) => {
       if (typeof detail.reservePub !== "string") {
         return Promise.reject(Error("reservePub missing"));
       }
       return wallet.withdrawPaybackReserve(detail.reservePub);
     },
-    ["get-coins"]: function (detail, sender) {
+    ["get-coins"]: (detail, sender) => {
       if (typeof detail.exchangeBaseUrl !== "string") {
         return Promise.reject(Error("exchangBaseUrl missing"));
       }
       return wallet.getCoins(detail.exchangeBaseUrl);
     },
-    ["get-precoins"]: function (detail, sender) {
+    ["get-precoins"]: (detail, sender) => {
       if (typeof detail.exchangeBaseUrl !== "string") {
         return Promise.reject(Error("exchangBaseUrl missing"));
       }
       return wallet.getPreCoins(detail.exchangeBaseUrl);
     },
-    ["get-denoms"]: function (detail, sender) {
+    ["get-denoms"]: (detail, sender) => {
       if (typeof detail.exchangeBaseUrl !== "string") {
         return Promise.reject(Error("exchangBaseUrl missing"));
       }
       return wallet.getDenoms(detail.exchangeBaseUrl);
     },
-    ["refresh-coin"]: function (detail, sender) {
+    ["refresh-coin"]: (detail, sender) => {
       if (typeof detail.coinPub !== "string") {
         return Promise.reject(Error("coinPub missing"));
       }
       return wallet.refresh(detail.coinPub);
     },
-    ["payback-coin"]: function (detail, sender) {
+    ["payback-coin"]: (detail, sender) => {
       if (typeof detail.coinPub !== "string") {
         return Promise.reject(Error("coinPub missing"));
       }
       return wallet.payback(detail.coinPub);
     },
-    ["payment-failed"]: function (detail, sender) {
+    ["payment-failed"]: (detail, sender) => {
       // For now we just update exchanges (maybe the exchange did something
       // wrong and the keys were messed up).
       // FIXME: in the future we should look at what actually went wrong.
@@ -280,9 +284,9 @@ function makeHandlers(db: IDBDatabase,
       wallet.updateExchanges();
       return Promise.resolve();
     },
-    ["payment-succeeded"]: function (detail, sender) {
-      let contractHash = detail.contractHash;
-      let merchantSig = detail.merchantSig;
+    ["payment-succeeded"]: (detail, sender) => {
+      const contractHash = detail.contractHash;
+      const merchantSig = detail.merchantSig;
       if (!contractHash) {
         return Promise.reject(Error("contractHash missing"));
       }
@@ -307,7 +311,7 @@ async function dispatch(handlers: any, req: any, sender: 
any, sendResponse: any)
 
   try {
     const p = handlers[req.type](req.detail, sender);
-    let r = await p;
+    const r = await p;
     try {
       sendResponse(r);
     } catch (e) {
@@ -317,7 +321,7 @@ async function dispatch(handlers: any, req: any, sender: 
any, sendResponse: any)
     console.log(`exception during wallet handler for '${req.type}'`);
     console.log("request", req);
     console.error(e);
-    let stack = undefined;
+    let stack;
     try {
       stack = e.stack.toString();
     } catch (e) {
@@ -325,9 +329,9 @@ async function dispatch(handlers: any, req: any, sender: 
any, sendResponse: any)
     }
     try {
       sendResponse({
-        stack,
         error: "exception",
         hint: e.message,
+        stack,
       });
     } catch (e) {
       console.log(e);
@@ -344,7 +348,7 @@ class ChromeNotifier implements Notifier {
       console.log("got connect!");
       this.ports.push(port);
       port.onDisconnect.addListener(() => {
-        let i = this.ports.indexOf(port);
+        const i = this.ports.indexOf(port);
         if (i >= 0) {
           this.ports.splice(i, 1);
         } else {
@@ -355,7 +359,7 @@ class ChromeNotifier implements Notifier {
   }
 
   notify() {
-    for (let p of this.ports) {
+    for (const p of this.ports) {
       p.postMessage({ notify: true });
     }
   }
@@ -365,7 +369,7 @@ class ChromeNotifier implements Notifier {
 /**
  * Mapping from tab ID to payment information (if any).
  */
-let paymentRequestCookies: { [n: number]: any } = {};
+const paymentRequestCookies: { [n: number]: any } = {};
 
 
 /**
@@ -376,19 +380,19 @@ let paymentRequestCookies: { [n: number]: any } = {};
  */
 function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url: 
string, tabId: number): any {
   const headers: { [s: string]: string } = {};
-  for (let kv of headerList) {
+  for (const kv of headerList) {
     if (kv.value) {
       headers[kv.name.toLowerCase()] = kv.value;
     }
   }
 
-  let fields = {
-    contract_url: headers["x-taler-contract-url"],
+  const fields = {
     contract_query: headers["x-taler-contract-query"],
+    contract_url: headers["x-taler-contract-url"],
     offer_url: headers["x-taler-offer-url"],
-  }
+  };
 
-  let talerHeaderFound = Object.keys(fields).filter((x: any) => (fields as 
any)[x]).length !== 0;
+  const talerHeaderFound = Object.keys(fields).filter((x: any) => (fields as 
any)[x]).length !== 0;
 
   if (!talerHeaderFound) {
     // looks like it's not a taler request, it might be
@@ -397,27 +401,26 @@ function handleHttpPayment(headerList: 
chrome.webRequest.HttpHeader[], url: stri
     return;
   }
 
-  let payDetail = {
+  const payDetail = {
     contract_url: fields.contract_url,
     offer_url: fields.offer_url,
   };
 
-  console.log("got pay detail", payDetail)
+  console.log("got pay detail", payDetail);
 
   // This cookie will be read by the injected content script
   // in the tab that displays the page.
   paymentRequestCookies[tabId] = {
-    type: "pay",
     payDetail,
+    type: "pay",
   };
 }
 
 
-
 function handleBankRequest(wallet: Wallet, headerList: 
chrome.webRequest.HttpHeader[],
-  url: string, tabId: number): any {
+                           url: string, tabId: number): any {
   const headers: { [s: string]: string } = {};
-  for (let kv of headerList) {
+  for (const kv of headerList) {
     if (kv.value) {
       headers[kv.name.toLowerCase()] = kv.value;
     }
@@ -432,7 +435,7 @@ function handleBankRequest(wallet: Wallet, headerList: 
chrome.webRequest.HttpHea
 
   const amount = headers["x-taler-amount"];
   if (amount) {
-    let callbackUrl = headers["x-taler-callback-url"];
+    const callbackUrl = headers["x-taler-callback-url"];
     if (!callbackUrl) {
       console.log("202 not understood (X-Taler-Callback-Url missing)");
       return;
@@ -441,30 +444,29 @@ function handleBankRequest(wallet: Wallet, headerList: 
chrome.webRequest.HttpHea
     try {
       amountParsed = JSON.parse(amount);
     } catch (e) {
-      let uri = new URI(chrome.extension.getURL("/src/pages/error.html"));
-      let p = {
+      const uri = new URI(chrome.extension.getURL("/src/pages/error.html"));
+      const p = {
         message: `Can't parse amount ("${amount}"): ${e.message}`,
       };
-      let redirectUrl = uri.query(p).href();
+      const redirectUrl = uri.query(p).href();
       // FIXME: use direct redirect when 
https://bugzilla.mozilla.org/show_bug.cgi?id=707624 is fixed
       chrome.tabs.update(tabId, {url: redirectUrl});
       return;
     }
-    let wtTypes = headers["x-taler-wt-types"];
+    const wtTypes = headers["x-taler-wt-types"];
     if (!wtTypes) {
       console.log("202 not understood (X-Taler-Wt-Types missing)");
       return;
     }
-    let params = {
-      amount: amount,
-      callback_url: new URI(callbackUrl)
-        .absoluteTo(url),
+    const params = {
+      amount,
       bank_url: url,
-      wt_types: wtTypes,
+      callback_url: new URI(callbackUrl) .absoluteTo(url),
       suggested_exchange_url: headers["x-taler-suggested-exchange"],
+      wt_types: wtTypes,
     };
-    let uri = new 
URI(chrome.extension.getURL("/src/pages/confirm-create-reserve.html"));
-    let redirectUrl = uri.query(params).href();
+    const uri = new 
URI(chrome.extension.getURL("/src/pages/confirm-create-reserve.html"));
+    const redirectUrl = uri.query(params).href();
     console.log("redirecting to", redirectUrl);
     // FIXME: use direct redirect when 
https://bugzilla.mozilla.org/show_bug.cgi?id=707624 is fixed
     chrome.tabs.update(tabId, {url: redirectUrl});
@@ -484,21 +486,21 @@ function clearRateLimitCache() {
 export async function wxMain() {
   window.onerror = (m, source, lineno, colno, error) => {
     logging.record("error", m + error, undefined, source || "(unknown)", 
lineno || 0, colno || 0);
-  }
+  };
 
   chrome.browserAction.setBadgeText({ text: "" });
   const badge = new ChromeBadge();
 
-  chrome.tabs.query({}, function (tabs) {
-    for (let tab of tabs) {
+  chrome.tabs.query({}, (tabs) => {
+    for (const tab of tabs) {
       if (!tab.url || !tab.id) {
         return;
       }
-      let uri = new URI(tab.url);
+      const uri = new URI(tab.url);
       if (uri.protocol() === "http" || uri.protocol() === "https") {
         console.log("injecting into existing tab", tab.id);
         chrome.tabs.executeScript(tab.id, { file: 
"/dist/contentScript-bundle.js" });
-        let code = `
+        const code = `
           if (("taler" in window) || 
document.documentElement.getAttribute("data-taler-nojs")) {
             document.dispatchEvent(new Event("taler-probe-result"));
           }
@@ -511,13 +513,13 @@ export async function wxMain() {
   const tabTimers: {[n: number]: number[]} = {};
 
   chrome.tabs.onRemoved.addListener((tabId, changeInfo) => {
-    let tt = tabTimers[tabId] || [];
-    for (let t of tt) {
+    const tt = tabTimers[tabId] || [];
+    for (const t of tt) {
       chrome.extension.getBackgroundPage().clearTimeout(t);
     }
   });
   chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
-    if (changeInfo.status !== 'complete') {
+    if (changeInfo.status !== "complete") {
       return;
     }
     const timers: number[] = [];
@@ -525,7 +527,7 @@ export async function wxMain() {
     const addRun = (dt: number) => {
       const id = chrome.extension.getBackgroundPage().setTimeout(run, dt);
       timers.push(id);
-    }
+    };
 
     const run = () => {
       timers.shift();
@@ -536,11 +538,11 @@ export async function wxMain() {
         if (!tab.url || !tab.id) {
           return;
         }
-        let uri = new URI(tab.url);
+        const uri = new URI(tab.url);
         if (!(uri.protocol() === "http" || uri.protocol() === "https")) {
           return;
         }
-        let code = `
+        const code = `
           if (("taler" in window) || 
document.documentElement.getAttribute("data-taler-nojs")) {
             document.dispatchEvent(new Event("taler-probe-result"));
           }
@@ -600,7 +602,6 @@ export async function wxMain() {
 }
 
 
-
 /**
  * Return a promise that resolves
  * to the taler wallet db.
@@ -620,13 +621,13 @@ function openTalerDb(): Promise<IDBDatabase> {
       switch (e.oldVersion) {
         case 0: // DB does not exist yet
 
-          for (let n in Stores) {
+          for (const n in Stores) {
             if ((Stores as any)[n] instanceof Store) {
-              let si: Store<any> = (Stores as any)[n];
+              const si: Store<any> = (Stores as any)[n];
               const s = db.createObjectStore(si.name, si.storeParams);
-              for (let indexName in (si as any)) {
+              for (const indexName in (si as any)) {
                 if ((si as any)[indexName] instanceof Index) {
-                  let ii: Index<any, any> = (si as any)[indexName];
+                  const ii: Index<any, any> = (si as any)[indexName];
                   s.createIndex(ii.indexName, ii.keyPath);
                 }
               }
@@ -649,31 +650,32 @@ function openTalerDb(): Promise<IDBDatabase> {
 
 
 function exportDb(db: IDBDatabase): Promise<any> {
-  let dump = {
+  const dump = {
     name: db.name,
-    version: db.version,
     stores: {} as {[s: string]: any},
+    version: db.version,
   };
 
   return new Promise((resolve, reject) => {
 
-    let tx = db.transaction(Array.from(db.objectStoreNames));
+    const tx = db.transaction(Array.from(db.objectStoreNames));
     tx.addEventListener("complete", () => {
       resolve(dump);
     });
+    // tslint:disable-next-line:prefer-for-of
     for (let i = 0; i < db.objectStoreNames.length; i++) {
-      let name = db.objectStoreNames[i];
-      let storeDump = {} as {[s: string]: any};
+      const name = db.objectStoreNames[i];
+      const storeDump = {} as {[s: string]: any};
       dump.stores[name] = storeDump;
-      let store = tx.objectStore(name)
-                    .openCursor()
-                    .addEventListener("success", (e: Event) => {
-                      let cursor = (e.target as any).result;
-                      if (cursor) {
-                        storeDump[cursor.key] = cursor.value;
-                        cursor.continue();
-                      }
-                    });
+      tx.objectStore(name)
+        .openCursor()
+        .addEventListener("success", (e: Event) => {
+          const cursor = (e.target as any).result;
+          if (cursor) {
+            storeDump[cursor.key] = cursor.value;
+            cursor.continue();
+          }
+        });
     }
   });
 }
@@ -682,17 +684,20 @@ function exportDb(db: IDBDatabase): Promise<any> {
 function importDb(db: IDBDatabase, dump: any): Promise<void> {
   console.log("importing db", dump);
   return new Promise<void>((resolve, reject) => {
-    let tx = db.transaction(Array.from(db.objectStoreNames), "readwrite");
-    for (let storeName in dump.stores) {
-      let objects = [];
-      for (let key in dump.stores[storeName]) {
-        objects.push(dump.stores[storeName][key]);
-      }
-      console.log(`importing ${objects.length} records into ${storeName}`); 
-      let store = tx.objectStore(storeName);
-      let clearReq = store.clear();
-      for (let obj of objects) {
-        store.put(obj);
+    const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite");
+    if (dump.stores) {
+      for (const storeName in dump.stores) {
+        const objects = [];
+        const dumpStore = dump.stores[storeName];
+        for (const key in dumpStore) {
+          objects.push(dumpStore[key]);
+        }
+        console.log(`importing ${objects.length} records into ${storeName}`);
+        const store = tx.objectStore(storeName);
+        const clearReq = store.clear();
+        for (const obj of objects) {
+          store.put(obj);
+        }
       }
     }
     tx.addEventListener("complete", () => {
diff --git a/tslint.json b/tslint.json
index 46a2004c..0e9f36f3 100644
--- a/tslint.json
+++ b/tslint.json
@@ -8,7 +8,26 @@
       "max-line-length": {
         "options": [120]
       },
-      "space-before-function-paren": [true, {"named": "never", "anonymous": 
"always"}]
+      "space-before-function-paren": [true, {"named": "never", "anonymous": 
"always"}],
+      "no-console": [false],
+      "no-consecutive-blank-lines": [true, 2],
+      "forin": false,
+      "member-access": false,
+      "variable-name": false,
+      "interface-name": false,
+      "max-classes-per-file": false,
+      "ordered-imports": [true,
+        {
+          "import-sources-order": "lowercase-last",
+          "named-imports-order": "lowercase-last"
+        }
+      ],
+      "no-namespace": false,
+      "member-ordering": false,
+      "array-type": [true, "array-simple"],
+      "class-name": false,
+      "no-bitwise": false,
+      "file-header": [true, "GNU General Public License"]
     },
     "rulesDirectory": []
 }

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



reply via email to

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