gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-wallet-webex] 03/03: wasm


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] 03/03: wasm
Date: Sat, 22 Sep 2018 17:19:55 +0200

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

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

commit 361463a2ff10bd3e536e34ee816b397c23dca6f7
Author: Florian Dold <address@hidden>
AuthorDate: Sat Sep 22 17:18:25 2018 +0200

    wasm
---
 emscripten/taler-emscripten-lib.js                 |   2 +-
 emscripten/taler-emscripten-lib.wasm               | Bin 443523 -> 444112 bytes
 gulpfile.js                                        |   1 +
 node_modules/nyc/node_modules/md5-hex/package.json |  64 +++-
 .../nyc/node_modules/path-exists/package.json      |  64 +++-
 .../nyc/node_modules/resolve-from/package.json     |  59 +++-
 package.json                                       |   1 +
 src/crypto/cryptoWorker.ts                         |  76 +++++
 src/crypto/emscInterface.ts                        |  72 +++-
 src/i18n/de.po                                     |  86 ++---
 src/i18n/en-US.po                                  |  86 ++---
 src/i18n/fr.po                                     |  86 ++---
 src/i18n/it.po                                     |  86 ++---
 src/i18n/strings.ts                                |  30 ++
 src/i18n/sv.po                                     |  86 ++---
 src/i18n/taler-wallet-webex.pot                    |  86 ++---
 webpack.config.js                                  |   4 +
 yarn.lock                                          | 374 ++++++++++++++++++++-
 18 files changed, 984 insertions(+), 279 deletions(-)

diff --git a/emscripten/taler-emscripten-lib.js 
b/emscripten/taler-emscripten-lib.js
index 5819e7e4..ce2a19d3 100644
--- a/emscripten/taler-emscripten-lib.js
+++ b/emscripten/taler-emscripten-lib.js
@@ -5,7 +5,7 @@ var TalerEmscriptenLib = (function() {
 function(TalerEmscriptenLib) {
   TalerEmscriptenLib = TalerEmscriptenLib || {};
 
-var Module=typeof TalerEmscriptenLib!=="undefined"?TalerEmscriptenLib:{};var 
moduleOverrides={};var key;for(key in 
Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw
 toThrow});Module["preRun"]=[];Module["postRun"]=[];var 
ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var 
ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typ 
[...]
+var Module=typeof TalerEmscriptenLib!=="undefined"?TalerEmscriptenLib:{};var 
moduleOverrides={};var key;for(key in 
Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw
 toThrow});Module["preRun"]=[];Module["postRun"]=[];var 
ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var 
ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typ 
[...]
 
 
 
diff --git a/emscripten/taler-emscripten-lib.wasm 
b/emscripten/taler-emscripten-lib.wasm
index ffb1bb0b..c52c2aac 100644
Binary files a/emscripten/taler-emscripten-lib.wasm and 
b/emscripten/taler-emscripten-lib.wasm differ
diff --git a/gulpfile.js b/gulpfile.js
index dcbeaa40..5bd5ebae 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -71,6 +71,7 @@ const paths = {
     "dist/*-bundle.js",
     "dist/*-bundle.js.map",
     "emscripten/taler-emscripten-lib.js",
+    "emscripten/taler-emscripten-lib.wasm",
     "img/icon.png",
     "img/logo.png",
     "src/webex/**/*.{js,css,html}",
diff --git a/node_modules/nyc/node_modules/md5-hex/package.json 
b/node_modules/nyc/node_modules/md5-hex/package.json
index 9dc26627..af28b07d 100644
--- a/node_modules/nyc/node_modules/md5-hex/package.json
+++ b/node_modules/nyc/node_modules/md5-hex/package.json
@@ -1,25 +1,58 @@
 {
-  "name": "md5-hex",
-  "version": "1.3.0",
-  "description": "Create a MD5 hash with hex encoding",
-  "license": "MIT",
-  "repository": "sindresorhus/md5-hex",
+  "_args": [
+    [
+      "address@hidden",
+      "/Users/benjamincoe/oss/nyc"
+    ]
+  ],
+  "_from": "address@hidden",
+  "_id": "address@hidden",
+  "_inBundle": false,
+  "_integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=",
+  "_location": "/md5-hex",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "address@hidden",
+    "name": "md5-hex",
+    "escapedName": "md5-hex",
+    "rawSpec": "1.3.0",
+    "saveSpec": null,
+    "fetchSpec": "1.3.0"
+  },
+  "_requiredBy": [
+    "/",
+    "/caching-transform"
+  ],
+  "_resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz";,
+  "_spec": "1.3.0",
+  "_where": "/Users/benjamincoe/oss/nyc",
   "author": {
     "name": "Sindre Sorhus",
     "email": "address@hidden",
     "url": "sindresorhus.com"
   },
   "browser": "browser.js",
+  "bugs": {
+    "url": "https://github.com/sindresorhus/md5-hex/issues";
+  },
+  "dependencies": {
+    "md5-o-matic": "^0.1.1"
+  },
+  "description": "Create a MD5 hash with hex encoding",
+  "devDependencies": {
+    "ava": "*",
+    "xo": "*"
+  },
   "engines": {
     "node": ">=0.10.0"
   },
-  "scripts": {
-    "test": "xo && ava"
-  },
   "files": [
     "index.js",
     "browser.js"
   ],
+  "homepage": "https://github.com/sindresorhus/md5-hex#readme";,
   "keywords": [
     "hash",
     "crypto",
@@ -29,11 +62,14 @@
     "browser",
     "browserify"
   ],
-  "dependencies": {
-    "md5-o-matic": "^0.1.1"
+  "license": "MIT",
+  "name": "md5-hex",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sindresorhus/md5-hex.git";
   },
-  "devDependencies": {
-    "ava": "*",
-    "xo": "*"
-  }
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "1.3.0"
 }
diff --git a/node_modules/nyc/node_modules/path-exists/package.json 
b/node_modules/nyc/node_modules/path-exists/package.json
index 5477ee8d..8abcc810 100644
--- a/node_modules/nyc/node_modules/path-exists/package.json
+++ b/node_modules/nyc/node_modules/path-exists/package.json
@@ -1,23 +1,56 @@
 {
-  "name": "path-exists",
-  "version": "2.1.0",
-  "description": "Check if a path exists",
-  "license": "MIT",
-  "repository": "sindresorhus/path-exists",
+  "_args": [
+    [
+      "address@hidden",
+      "/Users/benjamincoe/oss/nyc"
+    ]
+  ],
+  "_from": "address@hidden",
+  "_id": "address@hidden",
+  "_inBundle": false,
+  "_integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+  "_location": "/path-exists",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "address@hidden",
+    "name": "path-exists",
+    "escapedName": "path-exists",
+    "rawSpec": "2.1.0",
+    "saveSpec": null,
+    "fetchSpec": "2.1.0"
+  },
+  "_requiredBy": [
+    "/pkg-dir/find-up",
+    "/read-pkg-up/find-up"
+  ],
+  "_resolved": 
"https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz";,
+  "_spec": "2.1.0",
+  "_where": "/Users/benjamincoe/oss/nyc",
   "author": {
     "name": "Sindre Sorhus",
     "email": "address@hidden",
     "url": "sindresorhus.com"
   },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/path-exists/issues";
+  },
+  "dependencies": {
+    "pinkie-promise": "^2.0.0"
+  },
+  "description": "Check if a path exists",
+  "devDependencies": {
+    "ava": "*",
+    "xo": "*"
+  },
   "engines": {
     "node": ">=0.10.0"
   },
-  "scripts": {
-    "test": "xo && ava"
-  },
   "files": [
     "index.js"
   ],
+  "homepage": "https://github.com/sindresorhus/path-exists#readme";,
   "keywords": [
     "path",
     "exists",
@@ -30,11 +63,14 @@
     "access",
     "stat"
   ],
-  "dependencies": {
-    "pinkie-promise": "^2.0.0"
+  "license": "MIT",
+  "name": "path-exists",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sindresorhus/path-exists.git";
   },
-  "devDependencies": {
-    "ava": "*",
-    "xo": "*"
-  }
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "2.1.0"
 }
diff --git a/node_modules/nyc/node_modules/resolve-from/package.json 
b/node_modules/nyc/node_modules/resolve-from/package.json
index ee47da7c..2b18849c 100644
--- a/node_modules/nyc/node_modules/resolve-from/package.json
+++ b/node_modules/nyc/node_modules/resolve-from/package.json
@@ -1,23 +1,52 @@
 {
-  "name": "resolve-from",
-  "version": "2.0.0",
-  "description": "Resolve the path of a module like require.resolve() but from 
a given path",
-  "license": "MIT",
-  "repository": "sindresorhus/resolve-from",
+  "_args": [
+    [
+      "address@hidden",
+      "/Users/benjamincoe/oss/nyc"
+    ]
+  ],
+  "_from": "address@hidden",
+  "_id": "address@hidden",
+  "_inBundle": false,
+  "_integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
+  "_location": "/resolve-from",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "address@hidden",
+    "name": "resolve-from",
+    "escapedName": "resolve-from",
+    "rawSpec": "2.0.0",
+    "saveSpec": null,
+    "fetchSpec": "2.0.0"
+  },
+  "_requiredBy": [
+    "/"
+  ],
+  "_resolved": 
"https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz";,
+  "_spec": "2.0.0",
+  "_where": "/Users/benjamincoe/oss/nyc",
   "author": {
     "name": "Sindre Sorhus",
     "email": "address@hidden",
     "url": "sindresorhus.com"
   },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/resolve-from/issues";
+  },
+  "description": "Resolve the path of a module like require.resolve() but from 
a given path",
+  "devDependencies": {
+    "ava": "*",
+    "xo": "*"
+  },
   "engines": {
     "node": ">=0.10.0"
   },
-  "scripts": {
-    "test": "xo && ava"
-  },
   "files": [
     "index.js"
   ],
+  "homepage": "https://github.com/sindresorhus/resolve-from#readme";,
   "keywords": [
     "require",
     "resolve",
@@ -27,8 +56,14 @@
     "like",
     "path"
   ],
-  "devDependencies": {
-    "ava": "*",
-    "xo": "*"
-  }
+  "license": "MIT",
+  "name": "resolve-from",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sindresorhus/resolve-from.git";
+  },
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "2.0.0"
 }
diff --git a/package.json b/package.json
index 00a96acd..40e277b4 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,7 @@
     "vinyl": "^2.0.0",
     "vinyl-fs": "^2.4.3",
     "webpack": "^4.19.1",
+    "webpack-bundle-analyzer": "^3.0.2",
     "webpack-cli": "^3.1.0",
     "webpack-merge": "^4.1.0"
   }
diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts
index 3e71794b..11b21190 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -549,6 +549,76 @@ namespace RpcFunctions {
       time_eddsa_verify += timer.performanceNow() - start;
     }
 
+    /* rsa 2048 */
+
+    let time_rsa_2048_blind = 0;
+    const rsaPriv2048: native.RsaPrivateKey = 
native.RsaPrivateKey.create(2048);
+    const rsaPub2048 = rsaPriv2048.getPublicKey();
+    const blindingSecret2048 = native.RsaBlindingKeySecret.create();
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaBlind(h, blindingSecret2048, rsaPub2048);
+      time_rsa_2048_blind += timer.performanceNow() - start;
+    }
+
+    const blindedMessage2048 = native.rsaBlind(h, blindingSecret2048, 
rsaPub2048);
+    if (!blindedMessage2048) {
+      throw Error("should not happen");
+    }
+    const rsaBlindSig2048 = native.rsaSignBlinded(rsaPriv2048, 
blindedMessage2048);
+
+    let time_rsa_2048_unblind = 0;
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaUnblind(rsaBlindSig2048, blindingSecret2048, rsaPub2048);
+      time_rsa_2048_unblind += timer.performanceNow() - start;
+    }
+
+    const unblindedSig2048 = native.rsaUnblind(rsaBlindSig2048, 
blindingSecret2048, rsaPub2048);
+
+    let time_rsa_2048_verify = 0;
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaVerify(h, unblindedSig2048, rsaPub2048);
+      time_rsa_2048_verify += timer.performanceNow() - start;
+    }
+
+
+    /* rsa 4096 */
+
+    let time_rsa_4096_blind = 0;
+    const rsaPriv4096: native.RsaPrivateKey = 
native.RsaPrivateKey.create(4096);
+    const rsaPub4096 = rsaPriv4096.getPublicKey();
+    const blindingSecret4096 = native.RsaBlindingKeySecret.create();
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaBlind(h, blindingSecret4096, rsaPub4096);
+      time_rsa_4096_blind += timer.performanceNow() - start;
+    }
+
+    const blindedMessage4096 = native.rsaBlind(h, blindingSecret4096, 
rsaPub4096);
+    if (!blindedMessage4096) {
+      throw Error("should not happen");
+    }
+    const rsaBlindSig4096 = native.rsaSignBlinded(rsaPriv4096, 
blindedMessage4096);
+
+    let time_rsa_4096_unblind = 0;
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaUnblind(rsaBlindSig4096, blindingSecret4096, rsaPub4096);
+      time_rsa_4096_unblind += timer.performanceNow() - start;
+    }
+
+    const unblindedSig4096 = native.rsaUnblind(rsaBlindSig4096, 
blindingSecret4096, rsaPub4096);
+
+    let time_rsa_4096_verify = 0;
+    for (let i = 0; i < repetitions; i++) {
+      const start = timer.performanceNow();
+      native.rsaVerify(h, unblindedSig4096, rsaPub4096);
+      time_rsa_4096_verify += timer.performanceNow() - start;
+    }
+
+
     return {
       repetitions,
       time: {
@@ -558,6 +628,12 @@ namespace RpcFunctions {
         eddsa_sign: time_eddsa_sign,
         eddsa_verify: time_eddsa_verify,
         ecdsa_create: time_ecdsa_create,
+        rsa_2048_blind: time_rsa_2048_blind,
+        rsa_2048_unblind: time_rsa_2048_unblind,
+        rsa_2048_verify: time_rsa_2048_verify,
+        rsa_4096_blind: time_rsa_4096_blind,
+        rsa_4096_unblind: time_rsa_4096_unblind,
+        rsa_4096_verify: time_rsa_4096_verify,
       }
     };
   }
diff --git a/src/crypto/emscInterface.ts b/src/crypto/emscInterface.ts
index 61289fb7..dcd16e63 100644
--- a/src/crypto/emscInterface.ts
+++ b/src/crypto/emscInterface.ts
@@ -90,7 +90,9 @@ interface EmscFunctions {
   random_block(a1: number, a2: number, a3: number): void;
   rsa_blinding_key_free(a1: number): void;
   rsa_public_key_free(a1: number): void;
+  rsa_private_key_free(a1: number): void;
   rsa_signature_free(a1: number): void;
+  rsa_verify(msgHash: number, sig: number, pubKey: number): number;
   setup_fresh_coin(a1: number, a2: number, a3: number): void;
   string_to_data(a1: number, a2: number, a3: number, a4: number): number;
 }
@@ -115,10 +117,15 @@ interface EmscAllocFunctions {
   rsa_blinding_key_create(a1: number): number;
   rsa_blinding_key_decode(a1: number, a2: number): number;
   rsa_blinding_key_encode(a1: number, a2: number): number;
+  rsa_private_key_create(len: number): number;
+  rsa_private_key_decode(a1: number, a2: number): number;
+  rsa_private_key_encode(a1: number, a2: number): number;
+  rsa_private_key_get_public(privKeyPtr: number): number;
   rsa_public_key_decode(a1: number, a2: number): number;
   rsa_public_key_encode(a1: number, a2: number): number;
-  rsa_signature_encode(a1: number, a2: number): number;
   rsa_signature_decode(a1: number, a2: number): number;
+  rsa_signature_encode(a1: number, a2: number): number;
+  rsa_sign_blinded(keyPtr: number, msgPtr: number, msgLen: number): number;
   rsa_unblind(a1: number, a2: number, a3: number): number;
 }
 
@@ -159,10 +166,15 @@ class EmscEnvironment {
       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_private_key_create: getEmsc("GNUNET_CRYPTO_rsa_private_key_create", 
"number", ["number"]),
+      rsa_private_key_decode: getEmsc("GNUNET_CRYPTO_rsa_private_key_decode", 
"number", ["number", "number"]),
+      rsa_private_key_encode: getEmsc("GNUNET_CRYPTO_rsa_private_key_encode", 
"number", ["number", "number"]),
+      rsa_private_key_get_public: 
getEmsc("GNUNET_CRYPTO_rsa_private_key_get_public", "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_sign_blinded: getEmsc("GNUNET_CRYPTO_rsa_sign_blinded", "number", 
["number", "number", "number"]),
       rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind", "number", ["number", 
"number", "number"]),
     };
     this.funcs = {
@@ -189,7 +201,9 @@ class EmscEnvironment {
       random_block: getEmsc("GNUNET_CRYPTO_random_block", "void", ["number", 
"number", "number"]),
       rsa_blinding_key_free: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free", 
"void", ["number"]),
       rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free", 
"void", ["number"]),
+      rsa_private_key_free: getEmsc("GNUNET_CRYPTO_rsa_private_key_free", 
"void", ["number"]),
       rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free", "void", 
["number"]),
+      rsa_verify: getEmsc("GNUNET_CRYPTO_rsa_verify", "number", ["number", 
"number", "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"]),
     };
@@ -1358,6 +1372,42 @@ export class PaymentSignaturePS extends SignatureStruct {
 
 
 /**
+ * Low-level handle to an RsaPrivateKey.
+ */
+export class RsaPrivateKey extends MallocArenaObject {
+  static fromCrock(s: string): RsaPrivateKey {
+    return fromCrockDecoded(s, this, emsc().allocFuncs.rsa_private_key_decode);
+  }
+
+  static create(bitLen: number, a?: Arena): RsaPrivateKey {
+    const obj = new RsaPrivateKey(a);
+    obj.nativePtr = emsc().allocFuncs.rsa_private_key_create(bitLen);
+    return obj;
+  }
+
+  toCrock() {
+    return this.encode().toCrock();
+  }
+
+
+  getPublicKey(a?: Arena): RsaPublicKey {
+    const obj = new RsaPublicKey(a);
+    obj.nativePtr = 
emsc().allocFuncs.rsa_private_key_get_public(this.nativePtr);
+    return obj;
+  }
+
+  destroy() {
+    emsc().funcs.rsa_public_key_free(this.nativePtr);
+    this.nativePtr = 0;
+  }
+
+  encode(arena?: Arena): ByteArray {
+    return encode(this, emsc().allocFuncs.rsa_private_key_encode);
+  }
+}
+
+
+/**
  * Low-level handle to an RsaPublicKey.
  */
 export class RsaPublicKey extends MallocArenaObject {
@@ -1470,6 +1520,16 @@ export function eddsaVerify(purposeNum: number,
 }
 
 
+export function rsaVerify(h: HashCode,
+                          sig: RsaSignature,
+                          pub: RsaPublicKey) {
+  const r = emsc().funcs.rsa_verify(h.nativePtr,
+                                    sig.nativePtr,
+                                    pub.nativePtr);
+  return r === GNUNET_OK;
+}
+
+
 /**
  * Unblind a blindly signed value.
  */
@@ -1516,6 +1576,16 @@ export function ecdhEddsa(priv: EcdhePrivateKey,
   return h;
 }
 
+export function rsaSignBlinded(priv: RsaPrivateKey,
+                               msg: ByteArray): RsaSignature {
+  const sig = new RsaSignature();
+  sig.nativePtr = emsc().allocFuncs.rsa_sign_blinded (priv.nativePtr,
+                                                      msg.nativePtr,
+                                                      msg.size());
+  return sig;
+}
+
+
 
 /**
  * Derive a fresh coin from the given seed.  Used during refreshing.
diff --git a/src/i18n/de.po b/src/i18n/de.po
index 94ad58bb..1f6ee901 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, c-format
 msgid "show more details"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr ""
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,54 +66,54 @@ msgid ""
 "wallet."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, fuzzy, c-format
 msgid "Confirm payment"
 msgstr "Bezahlung bestätigen"
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
 "again."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, fuzzy, c-format
 msgid "Aborting payment ..."
 msgstr "Bezahlung bestätigen"
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, fuzzy, c-format
 msgid "Retry Payment"
 msgstr "Bezahlung bestätigen"
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, fuzzy, c-format
 msgid "Abort Payment"
 msgstr "Bezahlung bestätigen"
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, fuzzy, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr "Der Händler %1$s möchte einen Vertrag über %2$s mit Ihnen abschließen."
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
@@ -230,72 +240,72 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr "Saldo"
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr "Verlauf"
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr "Debug"
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, fuzzy, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr "Sie haben kein Digitalgeld. Wollen Sie %1$s? abheben?"
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, fuzzy, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr "Bank bestätig anlegen der Reserve (%1$s) bei %2$s"
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, fuzzy, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, fuzzy, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
@@ -303,17 +313,17 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, fuzzy, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, fuzzy, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
@@ -321,12 +331,12 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
@@ -334,22 +344,22 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index b9625d92..5d68c616 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, c-format
 msgid "show more details"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr ""
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,54 +66,54 @@ msgid ""
 "wallet."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
 "again."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, c-format
 msgid "Aborting payment ..."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, c-format
 msgid "Retry Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, c-format
 msgid "Abort Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
@@ -230,117 +240,117 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index 7f9fc14c..f097767a 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, c-format
 msgid "show more details"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr ""
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,54 +66,54 @@ msgid ""
 "wallet."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
 "again."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, c-format
 msgid "Aborting payment ..."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, c-format
 msgid "Retry Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, c-format
 msgid "Abort Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
@@ -230,117 +240,117 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
diff --git a/src/i18n/it.po b/src/i18n/it.po
index 7f9fc14c..f097767a 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, c-format
 msgid "show more details"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr ""
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,54 +66,54 @@ msgid ""
 "wallet."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
 "again."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, c-format
 msgid "Aborting payment ..."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, c-format
 msgid "Retry Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, c-format
 msgid "Abort Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
@@ -230,117 +240,117 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
diff --git a/src/i18n/strings.ts b/src/i18n/strings.ts
index b0d2208d..cb5ee7e6 100644
--- a/src/i18n/strings.ts
+++ b/src/i18n/strings.ts
@@ -24,6 +24,12 @@ strings['de'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Operation": [
+        ""
+      ],
+      "time (ms/op)": [
+        ""
+      ],
       "show more details": [
         ""
       ],
@@ -258,6 +264,12 @@ strings['en-US'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Operation": [
+        ""
+      ],
+      "time (ms/op)": [
+        ""
+      ],
       "show more details": [
         ""
       ],
@@ -492,6 +504,12 @@ strings['fr'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Operation": [
+        ""
+      ],
+      "time (ms/op)": [
+        ""
+      ],
       "show more details": [
         ""
       ],
@@ -726,6 +744,12 @@ strings['it'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Operation": [
+        ""
+      ],
+      "time (ms/op)": [
+        ""
+      ],
       "show more details": [
         ""
       ],
@@ -960,6 +984,12 @@ strings['sv'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Operation": [
+        ""
+      ],
+      "time (ms/op)": [
+        ""
+      ],
       "show more details": [
         "visa mer"
       ],
diff --git a/src/i18n/sv.po b/src/i18n/sv.po
index cff28fd3..890505c0 100644
--- a/src/i18n/sv.po
+++ b/src/i18n/sv.po
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, fuzzy, c-format
 msgid "show more details"
 msgstr "visa mer"
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr "Accepterade tjänsteleverantörer:"
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr "Tjänsteleverantörer i plånboken:"
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr "plånboken"
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,17 +66,17 @@ msgid ""
 "wallet."
 msgstr "plånboken"
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, c-format
 msgid "Confirm payment"
 msgstr "Godkän betalning"
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr "Bekräftar betalning"
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
@@ -75,37 +85,37 @@ msgstr ""
 "Du har redan betalat för det här, om du trycker \"Godkän betalning\" "
 "debiteras du inte igen"
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, c-format
 msgid "Aborting payment ..."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, c-format
 msgid "Retry Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, c-format
 msgid "Abort Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, fuzzy, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr "Säljaren %1$s erbjuder följande:"
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, fuzzy, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr "Det totala priset är %1$s (plus %2$s avgifter).\n"
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, fuzzy, c-format
 msgid "The total price is %1$s."
 msgstr "Det totala priset är %1$s."
@@ -234,119 +244,119 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr "Balans"
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr "Historia"
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr "hjälp"
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, fuzzy, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 "Du har ingen balans att visa. Behöver du\n"
 " %1$s att börja?\n"
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, fuzzy, c-format
 msgid "%1$s incoming"
 msgstr "%1$s inkommande"
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr "Återbetalning"
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr "Återlämna elektroniska pengar till bank konto"
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, fuzzy, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr "Säljaren %1$s erbjöd kontrakt %2$s.\n"
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr "Säljaren %1$sgav en återbetalning på %2$s.\n"
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr "Säljaren %1$sgav en återbetalning på %2$s.\n"
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr "plånboken"
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index 7f9fc14c..f097767a 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -27,28 +27,38 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/webex/pages/confirm-contract.tsx:76
+#: src/webex/pages/benchmark.tsx:58
+#, c-format
+msgid "Operation"
+msgstr ""
+
+#: src/webex/pages/benchmark.tsx:59
+#, c-format
+msgid "time (ms/op)"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:78
 #, c-format
 msgid "show more details"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:90
+#: src/webex/pages/confirm-contract.tsx:92
 #, c-format
 msgid "Accepted exchanges:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:95
+#: src/webex/pages/confirm-contract.tsx:97
 #, c-format
 msgid "Exchanges in the wallet:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:217
+#: src/webex/pages/confirm-contract.tsx:219
 #, c-format
 msgid "You have insufficient funds of the requested currency in your wallet."
 msgstr ""
 
 #. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:219
+#: src/webex/pages/confirm-contract.tsx:221
 #, c-format
 msgid ""
 "You do not have any funds from an exchange that is accepted by this "
@@ -56,54 +66,54 @@ msgid ""
 "wallet."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:320
+#: src/webex/pages/confirm-contract.tsx:322
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:330
+#: src/webex/pages/confirm-contract.tsx:332
 #, c-format
 msgid "Submitting payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:341
+#: src/webex/pages/confirm-contract.tsx:343
 #, c-format
 msgid ""
 "You already paid for this, clicking \"Confirm payment\" will not cost money "
 "again."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:355
+#: src/webex/pages/confirm-contract.tsx:357
 #, c-format
 msgid "Aborting payment ..."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:357
+#: src/webex/pages/confirm-contract.tsx:359
 #, c-format
 msgid "Payment aborted!"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:360
+#: src/webex/pages/confirm-contract.tsx:362
 #, c-format
 msgid "Retry Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:363
+#: src/webex/pages/confirm-contract.tsx:365
 #, c-format
 msgid "Abort Payment"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:372
+#: src/webex/pages/confirm-contract.tsx:374
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:381
+#: src/webex/pages/confirm-contract.tsx:383
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/confirm-contract.tsx:385
+#: src/webex/pages/confirm-contract.tsx:387
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
@@ -230,117 +240,117 @@ msgstr ""
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:165
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:165
+#: src/webex/pages/popup.tsx:168
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:168
+#: src/webex/pages/popup.tsx:171
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:248
+#: src/webex/pages/popup.tsx:251
 #, c-format
 msgid "help"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:253
+#: src/webex/pages/popup.tsx:256
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:270
+#: src/webex/pages/popup.tsx:273
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:283
+#: src/webex/pages/popup.tsx:286
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:310
+#: src/webex/pages/popup.tsx:313
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:337
+#: src/webex/pages/popup.tsx:340
 #, c-format
 msgid "Payback"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:338
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Return Electronic Cash to Bank Account"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:339
+#: src/webex/pages/popup.tsx:342
 #, c-format
 msgid "Manage Trusted Auditors and Exchanges"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:351
+#: src/webex/pages/popup.tsx:354
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:361
+#: src/webex/pages/popup.tsx:364
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:370
+#: src/webex/pages/popup.tsx:373
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:384
 #, c-format
 msgid "Withdrew %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:394
 #, c-format
 msgid "Paid %1$s to merchant %2$s. %3$s (%4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:401
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:411
+#: src/webex/pages/popup.tsx:414
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:415
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:419
+#: src/webex/pages/popup.tsx:422
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:424
+#: src/webex/pages/popup.tsx:427
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:467
+#: src/webex/pages/popup.tsx:470
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:492
+#: src/webex/pages/popup.tsx:495
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
diff --git a/webpack.config.js b/webpack.config.js
index c19b3add..f0c2a16c 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -47,14 +47,17 @@ module.exports = function (env) {
   const configWebWorker = {
     entry: {"cryptoWorker": "./src/crypto/cryptoWorker.ts"},
     target: "webworker",
+    name: "webworker",
   };
 
   const configBackground = {
     entry: {"background": "./src/webex/background.ts"},
+    name: "background",
   };
 
   const configContentScript = {
     entry: {"contentScript": "./src/webex/notify.ts"},
+    name: "contentScript",
   };
 
   const configExtensionPages = {
@@ -75,6 +78,7 @@ module.exports = function (env) {
       "tip": "./src/webex/pages/tip.tsx",
       "tree": "./src/webex/pages/tree.tsx",
     },
+    name: "pages",
     optimization: {
       splitChunks: {
         name: "page-common",
diff --git a/yarn.lock b/yarn.lock
index 23b09aa1..198bc9c0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -268,13 +268,20 @@ address@hidden:
   version "1.1.1"
   resolved 
"https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8";
 
address@hidden:
+  version "1.3.5"
+  resolved 
"https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2";
+  dependencies:
+    mime-types "~2.1.18"
+    negotiator "0.6.1"
+
 address@hidden:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278";
   dependencies:
     acorn "^5.0.0"
 
address@hidden, address@hidden:
address@hidden, address@hidden, address@hidden:
   version "5.7.3"
   resolved 
"https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279";
 
@@ -476,6 +483,10 @@ address@hidden:
   version "1.0.2"
   resolved 
"https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1";
 
address@hidden:
+  version "1.1.1"
+  resolved 
"https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2";
+
 address@hidden:
   version "0.2.3"
   resolved 
"https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5";
@@ -532,6 +543,10 @@ address@hidden:
   version "1.0.1"
   resolved 
"https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d";
 
address@hidden:
+  version "1.0.0"
+  resolved 
"https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8";
+
 address@hidden, address@hidden:
   version "2.6.1"
   resolved 
"https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610";
@@ -982,6 +997,15 @@ address@hidden:
   version "1.1.1"
   resolved 
"https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809";
 
address@hidden:
+  version "6.1.1"
+  resolved 
"https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48";
+  dependencies:
+    bluebird "^3.5.1"
+    check-types "^7.3.0"
+    hoopy "^0.1.2"
+    tryer "^1.0.0"
+
 address@hidden:
   version "3.2.0"
   resolved 
"https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e";
@@ -1005,6 +1029,21 @@ address@hidden, address@hidden, address@hidden, 
address@hidden:
   version "4.11.8"
   resolved 
"https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f";
 
address@hidden:
+  version "1.18.2"
+  resolved 
"https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454";
+  dependencies:
+    bytes "3.0.0"
+    content-type "~1.0.4"
+    debug "2.6.9"
+    depd "~1.1.1"
+    http-errors "~1.6.2"
+    iconv-lite "0.4.19"
+    on-finished "~2.3.0"
+    qs "6.5.1"
+    raw-body "2.3.2"
+    type-is "~1.6.15"
+
 address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e";
@@ -1166,7 +1205,7 @@ address@hidden:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8";
 
address@hidden:
address@hidden, address@hidden:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048";
 
@@ -1279,6 +1318,10 @@ address@hidden:
   version "0.7.0"
   resolved 
"https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e";
 
address@hidden:
+  version "7.4.0"
+  resolved 
"https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4";
+
 address@hidden:
   version "1.7.0"
   resolved 
"https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468";
@@ -1463,7 +1506,7 @@ address@hidden, address@hidden:
   version "2.17.1"
   resolved 
"https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf";
 
address@hidden:
address@hidden, address@hidden:
   version "2.18.0"
   resolved 
"https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970";
 
@@ -1552,6 +1595,14 @@ address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75";
 
address@hidden:
+  version "0.5.2"
+  resolved 
"https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4";
+
address@hidden:
+  version "1.0.4"
+  resolved 
"https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b";
+
 address@hidden, address@hidden, address@hidden, address@hidden:
   version "1.6.0"
   resolved 
"https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20";
@@ -1562,6 +1613,14 @@ address@hidden:
   version "1.0.2"
   resolved 
"https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715";
 
address@hidden:
+  version "1.0.6"
+  resolved 
"https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c";
+
address@hidden:
+  version "0.3.1"
+  resolved 
"https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb";
+
 address@hidden:
   version "1.0.5"
   resolved 
"https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0";
@@ -1739,15 +1798,15 @@ address@hidden:
   version "1.0.1"
   resolved 
"https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f";
 
address@hidden:
-  version "3.1.0"
-  resolved 
"https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261";
address@hidden, address@hidden, address@hidden, address@hidden, address@hidden, 
address@hidden:
+  version "2.6.9"
+  resolved 
"https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f";
   dependencies:
     ms "2.0.0"
 
address@hidden, address@hidden, address@hidden, address@hidden, address@hidden:
-  version "2.6.9"
-  resolved 
"https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f";
address@hidden:
+  version "3.1.0"
+  resolved 
"https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261";
   dependencies:
     ms "2.0.0"
 
@@ -1820,6 +1879,14 @@ address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a";
 
address@hidden:
+  version "1.1.1"
+  resolved 
"https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359";
+
address@hidden, address@hidden:
+  version "1.1.2"
+  resolved 
"https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9";
+
 address@hidden:
   version "0.0.1"
   resolved 
"https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19";
@@ -1831,6 +1898,10 @@ address@hidden:
     inherits "^2.0.1"
     minimalistic-assert "^1.0.0"
 
address@hidden:
+  version "1.0.4"
+  resolved 
"https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80";
+
 address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7";
@@ -1921,6 +1992,10 @@ address@hidden:
   version "0.1.4"
   resolved 
"https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2";
 
address@hidden:
+  version "0.1.1"
+  resolved 
"http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1";
+
 address@hidden, address@hidden, address@hidden:
   version "3.6.0"
   resolved 
"https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410";
@@ -1930,6 +2005,14 @@ address@hidden, address@hidden, address@hidden:
     readable-stream "^2.0.0"
     stream-shift "^1.0.0"
 
address@hidden:
+  version "1.1.1"
+  resolved 
"https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d";
+
address@hidden:
+  version "2.6.1"
+  resolved 
"https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0";
+
 address@hidden:
   version "6.4.1"
   resolved 
"https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a";
@@ -1953,6 +2036,10 @@ address@hidden:
     call-signature "0.0.2"
     core-js "^2.0.0"
 
address@hidden:
+  version "1.0.2"
+  resolved 
"https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59";
+
 address@hidden:
   version "0.1.12"
   resolved 
"https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb";
@@ -2026,6 +2113,10 @@ address@hidden, address@hidden:
     d "1"
     es5-ext "~0.10.14"
 
address@hidden:
+  version "1.0.3"
+  resolved 
"https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988";
+
 address@hidden, address@hidden, address@hidden:
   version "1.0.5"
   resolved 
"https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
@@ -2070,6 +2161,10 @@ address@hidden:
   version "2.0.2"
   resolved 
"https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b";
 
address@hidden:
+  version "1.8.1"
+  resolved 
"https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887";
+
 address@hidden:
   version "1.1.1"
   resolved 
"https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924";
@@ -2135,6 +2230,41 @@ address@hidden, address@hidden:
   dependencies:
     homedir-polyfill "^1.0.1"
 
address@hidden:
+  version "4.16.3"
+  resolved 
"http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53";
+  dependencies:
+    accepts "~1.3.5"
+    array-flatten "1.1.1"
+    body-parser "1.18.2"
+    content-disposition "0.5.2"
+    content-type "~1.0.4"
+    cookie "0.3.1"
+    cookie-signature "1.0.6"
+    debug "2.6.9"
+    depd "~1.1.2"
+    encodeurl "~1.0.2"
+    escape-html "~1.0.3"
+    etag "~1.8.1"
+    finalhandler "1.1.1"
+    fresh "0.5.2"
+    merge-descriptors "1.0.1"
+    methods "~1.1.2"
+    on-finished "~2.3.0"
+    parseurl "~1.3.2"
+    path-to-regexp "0.1.7"
+    proxy-addr "~2.0.3"
+    qs "6.5.1"
+    range-parser "~1.2.0"
+    safe-buffer "5.1.1"
+    send "0.16.2"
+    serve-static "1.13.2"
+    setprototypeof "1.1.0"
+    statuses "~1.4.0"
+    type-is "~1.6.16"
+    utils-merge "1.0.1"
+    vary "~1.1.2"
+
 address@hidden:
   version "1.1.4"
   resolved 
"https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071";
@@ -2215,6 +2345,10 @@ address@hidden:
   version "2.0.1"
   resolved 
"https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26";
 
address@hidden:
+  version "3.6.1"
+  resolved 
"https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317";
+
 address@hidden:
   version "2.2.4"
   resolved 
"https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565";
@@ -2234,6 +2368,18 @@ address@hidden:
     repeat-string "^1.6.1"
     to-regex-range "^2.1.0"
 
address@hidden:
+  version "1.1.1"
+  resolved 
"https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105";
+  dependencies:
+    debug "2.6.9"
+    encodeurl "~1.0.2"
+    escape-html "~1.0.3"
+    on-finished "~2.3.0"
+    parseurl "~1.3.2"
+    statuses "~1.4.0"
+    unpipe "~1.0.0"
+
 address@hidden:
   version "0.1.1"
   resolved 
"https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9";
@@ -2340,12 +2486,20 @@ address@hidden, address@hidden:
     cross-spawn "^4"
     signal-exit "^3.0.0"
 
address@hidden:
+  version "0.1.2"
+  resolved 
"https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84";
+
 address@hidden:
   version "0.2.1"
   resolved 
"https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19";
   dependencies:
     map-cache "^0.2.2"
 
address@hidden:
+  version "0.5.2"
+  resolved 
"https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7";
+
 address@hidden:
   version "2.3.0"
   resolved 
"https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af";
@@ -2795,6 +2949,13 @@ address@hidden:
   dependencies:
     glogg "^1.0.0"
 
address@hidden:
+  version "5.0.0"
+  resolved 
"https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80";
+  dependencies:
+    duplexer "^0.1.1"
+    pify "^3.0.0"
+
 address@hidden, address@hidden:
   version "4.0.12"
   resolved 
"https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5";
@@ -2915,6 +3076,10 @@ address@hidden:
   dependencies:
     parse-passwd "^1.0.0"
 
address@hidden:
+  version "0.1.4"
+  resolved 
"https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d";
+
 address@hidden:
   version "2.7.1"
   resolved 
"https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047";
@@ -2951,6 +3116,24 @@ address@hidden:
     domutils "1.1"
     readable-stream "1.0"
 
address@hidden:
+  version "1.6.2"
+  resolved 
"https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736";
+  dependencies:
+    depd "1.1.1"
+    inherits "2.0.3"
+    setprototypeof "1.0.3"
+    statuses ">= 1.3.1 < 2"
+
address@hidden:
+  version "1.6.3"
+  resolved 
"http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d";
+  dependencies:
+    depd "~1.1.2"
+    inherits "2.0.3"
+    setprototypeof "1.1.0"
+    statuses ">= 1.4.0 < 2"
+
 address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73";
@@ -2974,6 +3157,10 @@ address@hidden:
     resolve-from "^3.0.0"
     safe-buffer "^5.0.1"
 
address@hidden:
+  version "0.4.19"
+  resolved 
"https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b";
+
 address@hidden, address@hidden, address@hidden:
   version "0.4.24"
   resolved 
"https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b";
@@ -3093,6 +3280,10 @@ address@hidden:
   version "2.0.0"
   resolved 
"https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02";
 
address@hidden:
+  version "1.8.0"
+  resolved 
"https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e";
+
 address@hidden:
   version "1.4.0"
   resolved 
"https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766";
@@ -3872,6 +4063,10 @@ address@hidden:
     hash-base "^3.0.0"
     inherits "^2.0.1"
 
address@hidden:
+  version "0.3.0"
+  resolved 
"https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748";
+
 address@hidden:
   version "1.1.0"
   resolved 
"https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76";
@@ -3908,6 +4103,10 @@ address@hidden:
     redent "^1.0.0"
     trim-newlines "^1.0.0"
 
address@hidden:
+  version "1.0.1"
+  resolved 
"https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61";
+
 address@hidden:
   version "1.1.0"
   resolved 
"https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646";
@@ -3920,6 +4119,10 @@ address@hidden:
   dependencies:
     readable-stream "^2.0.1"
 
address@hidden:
+  version "1.1.2"
+  resolved 
"https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee";
+
 address@hidden, address@hidden, address@hidden:
   version "2.3.11"
   resolved 
"https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565";
@@ -3963,6 +4166,20 @@ address@hidden:
     bn.js "^4.0.0"
     brorand "^1.0.1"
 
address@hidden:
+  version "1.36.0"
+  resolved 
"https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397";
+
address@hidden:
+  version "2.1.20"
+  resolved 
"https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19";
+  dependencies:
+    mime-db "~1.36.0"
+
address@hidden:
+  version "1.4.1"
+  resolved 
"https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6";
+
 address@hidden:
   version "1.2.0"
   resolved 
"https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022";
@@ -4121,6 +4338,10 @@ address@hidden:
     iconv-lite "^0.4.4"
     sax "^1.2.4"
 
address@hidden:
+  version "0.6.1"
+  resolved 
"https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9";
+
 address@hidden:
   version "2.5.2"
   resolved 
"https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.2.tgz#489105ce7bc54e709d736b195f82135048c50fcc";
@@ -4360,6 +4581,12 @@ address@hidden:
     is-observable "^0.2.0"
     symbol-observable "^1.0.4"
 
address@hidden:
+  version "2.3.0"
+  resolved 
"https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947";
+  dependencies:
+    ee-first "1.1.1"
+
 address@hidden, address@hidden, address@hidden, address@hidden:
   version "1.4.0"
   resolved 
"https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1";
@@ -4378,6 +4605,10 @@ address@hidden:
   dependencies:
     mimic-fn "^1.0.0"
 
address@hidden:
+  version "1.5.1"
+  resolved 
"https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed";
+
 address@hidden:
   version "0.6.1"
   resolved 
"https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686";
@@ -4587,6 +4818,10 @@ address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6";
 
address@hidden:
+  version "1.3.2"
+  resolved 
"https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3";
+
 address@hidden:
   version "0.1.1"
   resolved 
"https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14";
@@ -4635,6 +4870,10 @@ address@hidden:
   dependencies:
     path-root-regex "^0.1.0"
 
address@hidden:
+  version "0.1.7"
+  resolved 
"https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c";
+
 address@hidden:
   version "1.1.0"
   resolved 
"https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441";
@@ -4809,6 +5048,13 @@ address@hidden:
     loose-envify "^1.3.1"
     object-assign "^4.1.1"
 
address@hidden:
+  version "2.0.4"
+  resolved 
"https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93";
+  dependencies:
+    forwarded "~0.1.2"
+    ipaddr.js "1.8.0"
+
 address@hidden:
   version "1.0.1"
   resolved 
"https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476";
@@ -4854,6 +5100,10 @@ address@hidden:
   version "2.1.1"
   resolved 
"https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec";
 
address@hidden:
+  version "6.5.1"
+  resolved 
"https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8";
+
 address@hidden:
   version "0.2.1"
   resolved 
"https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73";
@@ -4883,6 +5133,19 @@ address@hidden:
     randombytes "^2.0.5"
     safe-buffer "^5.1.0"
 
address@hidden:
+  version "1.2.0"
+  resolved 
"https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e";
+
address@hidden:
+  version "2.3.2"
+  resolved 
"https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89";
+  dependencies:
+    bytes "3.0.0"
+    http-errors "1.6.2"
+    iconv-lite "0.4.19"
+    unpipe "1.0.0"
+
 address@hidden, address@hidden, address@hidden:
   version "1.2.8"
   resolved 
"https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed";
@@ -5195,6 +5458,10 @@ address@hidden:
   dependencies:
     tslib "^1.9.0"
 
address@hidden:
+  version "5.1.1"
+  resolved 
"https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853";
+
 address@hidden, address@hidden, address@hidden, address@hidden, 
address@hidden, address@hidden:
   version "5.1.2"
   resolved 
"https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d";
@@ -5240,6 +5507,24 @@ address@hidden:
   version "4.3.6"
   resolved 
"https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da";
 
address@hidden:
+  version "0.16.2"
+  resolved 
"https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1";
+  dependencies:
+    debug "2.6.9"
+    depd "~1.1.2"
+    destroy "~1.0.4"
+    encodeurl "~1.0.2"
+    escape-html "~1.0.3"
+    etag "~1.8.1"
+    fresh "0.5.2"
+    http-errors "~1.6.2"
+    mime "1.4.1"
+    ms "2.0.0"
+    on-finished "~2.3.0"
+    range-parser "~1.2.0"
+    statuses "~1.4.0"
+
 address@hidden:
   version "0.0.7"
   resolved 
"https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c";
@@ -5248,6 +5533,15 @@ address@hidden:
   version "1.5.0"
   resolved 
"https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe";
 
address@hidden:
+  version "1.13.2"
+  resolved 
"https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1";
+  dependencies:
+    encodeurl "~1.0.2"
+    escape-html "~1.0.3"
+    parseurl "~1.3.2"
+    send "0.16.2"
+
 address@hidden, address@hidden:
   version "2.0.0"
   resolved 
"https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7";
@@ -5274,6 +5568,14 @@ address@hidden:
   version "1.0.5"
   resolved 
"https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285";
 
address@hidden:
+  version "1.0.3"
+  resolved 
"https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04";
+
address@hidden:
+  version "1.1.0"
+  resolved 
"https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656";
+
 address@hidden, address@hidden:
   version "2.4.11"
   resolved 
"http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7";
@@ -5461,6 +5763,14 @@ address@hidden:
     define-property "^0.2.5"
     object-copy "^0.1.0"
 
+"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2":
+  version "1.5.0"
+  resolved 
"https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c";
+
address@hidden:
+  version "1.4.0"
+  resolved 
"https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087";
+
 address@hidden:
   version "2.0.1"
   resolved 
"https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db";
@@ -5808,6 +6118,10 @@ address@hidden:
   version "1.0.1"
   resolved 
"https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003";
 
address@hidden:
+  version "1.0.1"
+  resolved 
"https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8";
+
 address@hidden, address@hidden, address@hidden:
   version "1.9.3"
   resolved 
"https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286";
@@ -5839,6 +6153,13 @@ address@hidden:
   version "0.0.0"
   resolved 
"https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6";
 
address@hidden, address@hidden:
+  version "1.6.16"
+  resolved 
"https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194";
+  dependencies:
+    media-typer "0.3.0"
+    mime-types "~2.1.18"
+
 address@hidden:
   version "0.0.6"
   resolved 
"https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777";
@@ -5966,6 +6287,10 @@ address@hidden:
   version "0.1.2"
   resolved 
"https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66";
 
address@hidden, address@hidden:
+  version "1.0.0"
+  resolved 
"https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec";
+
 address@hidden:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559";
@@ -6059,6 +6384,10 @@ address@hidden:
   version "0.4.0"
   resolved 
"https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c";
 
address@hidden:
+  version "1.0.1"
+  resolved 
"https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713";
+
 address@hidden:
   version "3.3.2"
   resolved 
"https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131";
@@ -6088,6 +6417,10 @@ address@hidden:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813";
 
address@hidden:
+  version "1.1.2"
+  resolved 
"https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc";
+
 address@hidden:
   version "0.3.14"
   resolved 
"https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6";
@@ -6209,6 +6542,23 @@ address@hidden:
     graceful-fs "^4.1.2"
     neo-async "^2.5.0"
 
address@hidden:
+  version "3.0.2"
+  resolved 
"https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.2.tgz#22f19ea6d1b5a15fd7a90baae0bc0f39bd1e4d48";
+  dependencies:
+    acorn "^5.7.3"
+    bfj "^6.1.1"
+    chalk "^2.4.1"
+    commander "^2.18.0"
+    ejs "^2.6.1"
+    express "^4.16.3"
+    filesize "^3.6.1"
+    gzip-size "^5.0.0"
+    lodash "^4.17.10"
+    mkdirp "^0.5.1"
+    opener "^1.5.1"
+    ws "^6.0.0"
+
 address@hidden:
   version "3.1.0"
   resolved 
"https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994";
@@ -6357,6 +6707,12 @@ address@hidden:
     sort-keys "^2.0.0"
     write-json-file "^2.2.0"
 
address@hidden:
+  version "6.0.0"
+  resolved 
"https://registry.yarnpkg.com/ws/-/ws-6.0.0.tgz#eaa494aded00ac4289d455bac8d84c7c651cef35";
+  dependencies:
+    async-limiter "~1.0.0"
+
 address@hidden:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4";

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



reply via email to

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