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 (1751ecb1 -> 361


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] branch master updated (1751ecb1 -> 361463a2)
Date: Sat, 22 Sep 2018 17:19:52 +0200

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

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

    from 1751ecb1 benchmark
     new 74fe752e not working
     new 1f9ca30a wasm
     new 361463a2 wasm

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


Summary of changes:
 emscripten/taler-emscripten-lib.js                 |  32 +-
 emscripten/taler-emscripten-lib.wasm               | Bin 0 -> 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                         |  96 ++++-
 src/crypto/emscInterface.ts                        | 453 ++++++++++++++-------
 src/crypto/emscLoader.d.ts                         |   8 +-
 src/crypto/emscLoader.js                           |  27 +-
 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 ++++++++++++++++-
 20 files changed, 1282 insertions(+), 447 deletions(-)
 create mode 100644 emscripten/taler-emscripten-lib.wasm

diff --git a/emscripten/taler-emscripten-lib.js 
b/emscripten/taler-emscripten-lib.js
index dcbea842..ce2a19d3 100644
--- a/emscripten/taler-emscripten-lib.js
+++ b/emscripten/taler-emscripten-lib.js
@@ -1,22 +1,24 @@
-var Module;if(!Module)Module=(typeof 
TalerEmscriptenLib!=="undefined"?TalerEmscriptenLib:null)||{};var 
moduleOverrides={};for(var key in 
Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var 
ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var 
ENVIRONMENT_IS_NODE=false;var 
ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else
 if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if [...]
-var asm=(function(global,env,buffer) {
-"use asm";var a=new global.Int8Array(buffer);var b=new 
global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new 
global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new 
global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new 
global.Float64Array(buffer);var i=env.DYNAMICTOP_PTR|0;var 
j=env.tempDoublePtr|0;var k=env.ABORT|0;var l=env.STACKTOP|0;var 
m=env.STACK_MAX|0;var n=env.cttz_i8|0;var o=0;var p=0;var q=0;var r=0;var 
s=global.NaN,t=glob [...]
-// EMSCRIPTEN_START_FUNCS
-function Ab(a){a=a|0;var 
b=0;b=l;l=l+a|0;l=l+15&-16;if((l|0)>=(m|0))$(a|0);return b|0}function 
Bb(){return l|0}function Cb(a){a=a|0;l=a}function 
Db(a,b){a=a|0;b=b|0;l=a;m=b}function 
Eb(a,b){a=a|0;b=b|0;if(!o){o=a;p=b}}function Fb(a){a=a|0;D=a}function 
Gb(){return D|0}function Hb(a){a=a|0;var b=0;b=Pb(32,19010,38)|0;jc(a,b);return 
b|0}function Ib(a){a=a|0;var b=0;b=Pb(32,19010,56)|0;hc(a,b);return 
b|0}function Jb(a){a=a|0;var b=0;b=Pb(32,19010,73)|0;lc(a,b);return 
b|0}function Kb(b,c,d){b [...]
-function rm(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var 
h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=c[b+12>>2]|0;s=c[t+36>>2]|0;t=c[t+20>>2]|0;if(e>>>0<g>>>0){u=200;return
 
u|0}u=b+112|0;e=c[u>>2]|0;if(e>>>0>=g>>>0){h=b+64+t+(0-e)|0;if(!((f|d|h)&3))if(g>>>0>3){l=g+-4|0;m=l&-4;o=m+4|0;n=f+o|0;i=h;j=d;k=g;while(1){c[j>>2]=c[f>>2]^c[i>>2];k=k+-4|0;if(k>>>0<=3)break;else{f=f+4|0;i=i+4|0;j=j+4|0}}i=l-m|0;f=n;h=h+o|0;d=d+o|0}else
 i=g;else i=g;if(i){e=i;while(1){a[d>>0]=a[f>>0]^a[ [...]
-function Pf(b){b=b|0;var d=0;if(!b){Tn(22);d=0;return 
d|0}if(!(c[17594]|0)){d=Xf(b)|0;return d|0}d=Xf(b+5|0)|0;if(!d){d=0;return 
d|0}a[d>>0]=b;a[d+1>>0]=b>>>8;a[d+2>>0]=b>>>16;a[d+3>>0]=-52;a[d+(b+4)>>0]=-86;d=d+4|0;return
 d|0}function Qf(b,e){b=b|0;e=e|0;var 
f=0,g=0,h=0,i=0,j=0;j=l;l=l+16|0;if((l|0)>=(m|0))$(16);g=j+8|0;f=j;if(!(c[17594]|0))if(!(ag(b)|0)){e=Rq(b,e)|0;l=j;return
 e|0}else{e=$f(b,e)|0;l=j;return e|0}if(!b){if(!e){Tn(22);e=0;l=j;return 
e|0}f=Oq(e+5|0)|0;if(!f){e=0;l=j;retur [...]
-function Mk(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var 
g=0,h=0,i=0,j=0,k=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0;fa=l;l=l+208|0;if((l|0)>=(m|0))$(208);U=fa+136|0;T=fa+72|0;R=fa+40|0;H=fa+20|0;I=fa;v=c[e+4>>2]|0;V=c[f+4>>2]|0;r=V<<1;W=c[f+8>>2]|0;g=v<<5;if((g|0)<=512)if((g|0)<=256)if((g|0)>128)D=3;else
 D=(g|0)>64?2:1;else D=4;else D=5;u=c[e [...]
-function mi(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var 
h=0,i=0,j=0,k=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=
 [...]
-function ij(b,e,f){b=b|0;e=e|0;f=f|0;var 
g=0,h=0,i=0,j=0,k=0,l=0,m=0;i=((d[f+2>>0]|0)<<16|(d[f+3>>0]|0)<<24|(d[f+1>>0]|0)<<8|(d[f>>0]|0))^c[b+4096>>2];g=((d[f+6>>0]|0)<<16|(d[f+7>>0]|0)<<24|(d[f+5>>0]|0)<<8|(d[f+4>>0]|0))^c[b+4100>>2];h=((d[f+14>>0]|0)<<16|(d[f+15>>0]|0)<<24|(d[f+13>>0]|0)<<8|(d[f+12>>0]|0))^c[b+4108>>2];k=c[b+2048+((g>>>8&255)<<2)>>2]^c[b+1024+((g&255)<<2)>>2]^c[b+3072+((g>>>16&255)<<2)>>2]^c[b+(g>>>24<<2)>>2];j=k+(c[b+1024+((i>>>8&255)<<2)>>2]^c[b+((i&255)<<2)>>2]^c[b+
 [...]
-function op(e,f,g,i,k){e=e|0;f=f|0;g=g|0;i=i|0;k=k|0;var 
n=0,o=0,p=0,q=0,r=0.0,s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0,B=0,C=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0;la=l;l=l+624|0;if((l|0)>=(m|0))$(624);ha=la+24|0;ia=la+16|0;ja=la+588|0;Z=la+576|0;ka=la;U=la+536|0;O=la+8|0;P=la+528|0;Q=(e|0)!=0;R=U+40|0;T=R;U=U+39|0;V=O+4|0;W=ja;X=0-W|0;Y=Z+12|0;Z=Z+11|0;_=Y;aa=_-W|0;ba=-2-W|0;ca=_
 [...]
 
-// EMSCRIPTEN_END_FUNCS
-var 
pb=[Ar,Yh,Zh,_h,$h,Gi,Hi,Ii,Ji,Li,Ti,_i,ej,hj,ij,jj,Bm,Cm,Dm,Em,Gm,Gg,Nm,wo,xo,Bo,Ap,Ke,Rp,gi,hi,ri,Ui,$i,fj,Do,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar,Ar];var
 qb=[Br,ki,fi,ei,di,mi,mj,nj,lj,Br,Br,Br,Br,Br,Br,Br];var 
rb=[Cr,pi,Ri,Yi,cj,Xj,sq,Cr];var sb=[Dr,oi,Qi,Xi,aj,bj,gj,Mm];var 
tb=[Er,qi,Fi,Ki,Si,Zi,dj,Am,Fm,Jg,vo,Er,Er,Er,Er,Er];var 
ub=[Fr,Jm,ni,$m,qn,zn,to,Fr];var vb=[Gr,ii,ji,eo];var wb=[Hr,Om,jm,Dn];var 
xb=[Ir,li];var yb=[Jr,Ei,Mi,zm,H [...]
+var TalerEmscriptenLib = (function() {
+  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? 
document.currentScript.src : undefined;
+  return (
+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 
[...]
 
-// EMSCRIPTEN_END_ASM
-(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var 
real__bitshift64Lshr=asm["_bitshift64Lshr"];asm["_bitshift64Lshr"]=(function(){assert(runtimeInitialized,"you
 need to wait for the runtime to be ready (e.g. wait for main() to be 
called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to 
keep it alive after main() exits)");return 
real__bitshift64Lshr.apply(null,arguments)});var 
real__bitshift64Ashr=asm["_bitshift64Ashr"];asm["_bitshift64Ashr"]=(function(){assert(r
 [...]
 
 
 
 
+  return TalerEmscriptenLib;
+}
+);
+})();
+if (typeof exports === 'object' && typeof module === 'object')
+    module.exports = TalerEmscriptenLib;
+  else if (typeof define === 'function' && define['amd'])
+    define([], function() { return TalerEmscriptenLib; });
+  else if (typeof exports === 'object')
+    exports["TalerEmscriptenLib"] = TalerEmscriptenLib;
+  
\ No newline at end of file
diff --git a/emscripten/taler-emscripten-lib.wasm 
b/emscripten/taler-emscripten-lib.wasm
new file mode 100644
index 00000000..c52c2aac
Binary files /dev/null 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 7cec5f28..11b21190 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -53,6 +53,8 @@ import {
 
 import { canonicalJson } from "../helpers";
 
+import * as emscLoader from "./emscLoader";
+
 import {
   Amount,
   EddsaPublicKey,
@@ -547,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: {
@@ -556,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,
       }
     };
   }
@@ -580,6 +658,20 @@ worker.onmessage = (msg: MessageEvent) => {
     console.error(`unknown operation: '${msg.data.operation}'`);
     return;
   }
-  const res = f(...msg.data.args);
-  worker.postMessage({result: res, id: msg.data.id});
+
+  console.log("onmessage with", msg.data.operation);
+  console.log("foo");
+
+  emscLoader.getLib().then((p) => {
+    const lib = p.lib;
+    if (!native.isInitialized()) {
+      console.log("initializing emscripten for then first time with lib");
+      native.initialize(lib);
+    }
+
+    console.log("about to execute", msg.data.operation);
+    const res = f(...msg.data.args);
+    console.log("finished executing", msg.data.operation);
+    worker.postMessage({ result: res, id: msg.data.id });
+  });
 };
diff --git a/src/crypto/emscInterface.ts b/src/crypto/emscInterface.ts
index 0662f4a7..dcd16e63 100644
--- a/src/crypto/emscInterface.ts
+++ b/src/crypto/emscInterface.ts
@@ -28,9 +28,34 @@
  */
 import { AmountJson } from "../amounts";
 
-import { EmscFunGen, getLib } from "./emscLoader";
+import { EmscFunGen, EmscLib } from "./emscLoader";
 
-const emscLib = getLib();
+
+// Will be set only after initialization.
+let maybeEmscEnv: EmscEnvironment | undefined = undefined;
+
+export function isInitialized() {
+  return !!maybeEmscEnv;
+}
+
+
+export function initialize(lib: EmscLib) {
+  if (!lib) {
+    throw Error("library must be object");
+  }
+  if (maybeEmscEnv) {
+    throw Error("emsc lib already initialized");
+  }
+  maybeEmscEnv = new EmscEnvironment(lib);
+}
+
+
+function emsc() {
+  if (maybeEmscEnv) {
+    return maybeEmscEnv;
+  }
+  throw Error("cannot use taler emscripten before initialization");
+}
 
 
 /**
@@ -41,75 +66,149 @@ const PTR_SIZE = 4;
 
 const GNUNET_OK = 1;
 
+interface EmscFunctions {
+  amount_add(a1: number, a2: number, a3: number): number;
+  amount_cmp(a1: number, a2: number): number;
+  amount_get_zero(a1: string, a2: number): number;
+  amount_hton(a1: number, a2: number): void;
+  amount_normalize(a1: number): void;
+  amount_ntoh(a1: number, a2: number): void;
+  amount_subtract(a1: number, a2: number, a3: number): number;
+  ecdh_eddsa(a1: number, a2: number, a3: number): number;
+  eddsa_sign(a1: number, a2: number, a3: number): number;
+  eddsa_verify(a1: number, a2: number, a3: number, a4: number): number;
+  free(ptr: number): void;
+  get_currency(a: number): string;
+  get_fraction(a: number): number;
+  get_value(a: number): number;
+  hash(a1: number, a2: number, a3: number): void;
+  hash_context_abort(ctx: number): void;
+  hash_context_finish(a1: number, a2: number): void;
+  hash_context_read(a1: number, a2: number, a3: number): void;
+  hash_create_random(a1: number, a2: number): void;
+  memmove(a1: number, a2: number, a3: number): number;
+  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;
+}
 
-/**
- * Get an emscripten-compiled function.
- */
-const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => {
-  return (...args: any[]) => {
-    return emscLib.ccall(name, ret, argTypes, args);
-  };
-};
+interface EmscAllocFunctions {
+  data_to_string_alloc(a1: number, a2: number): number;
+  ecdhe_key_create(): number;
+  ecdhe_public_key_from_private(a1: number): number;
+  ecdsa_key_create(): number;
+  ecdsa_public_key_from_private(a1: number): number;
+  eddsa_key_create(): number;
+  eddsa_public_key_from_private(a1: number): number;
+  /**
+   * Note that value_1 and value_2 are the first 64-bit parameter,
+   * and not two separate parameters (by the emscripten calling convention).
+   */
+  get_amount(value_1: number, value_2: number, fraction: number, currency: 
string): number;
+  hash_context_start(): number;
+  malloc(size: number): number;
+  purpose_create(a1: number, a2: number, a3: number): number;
+  rsa_blind(a1: number, a2: number, a3: number, a4: number, a5: number): 
number;
+  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_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;
+}
 
+class EmscEnvironment {
 
-/**
- * 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_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"]),
-};
+  /**
+   * Emscripten functions that don't do any memory allocations.
+   */
+  public funcs: EmscFunctions;
+
+  /**
+   * Emscripten functions that allocate memory.
+   */
+  public allocFuncs: EmscAllocFunctions;
 
+  public lib: EmscLib;
 
-/**
- * Emscripten functions that allocate memory.
- */
-const emscAlloc = {
-  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"]),
-};
+  constructor(lib: EmscLib) {
+    const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => {
+      return (...args: any[]) => {
+        return lib.ccall(name, ret, argTypes, args);
+      };
+    };
+    this.lib = lib;
+    this.allocFuncs = {
+      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) => lib._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_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 = {
+      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) => lib._free(ptr),
+      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_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"]),
+    };
+  }
+}
 
 
 /**
@@ -152,7 +251,7 @@ export class HashContext implements ArenaObject {
   private hashContextPtr: number | undefined;
 
   constructor() {
-    this.hashContextPtr = emscAlloc.hash_context_start();
+    this.hashContextPtr = emsc().allocFuncs.hash_context_start();
   }
 
   /**
@@ -162,7 +261,7 @@ export class HashContext implements ArenaObject {
     if (!this.hashContextPtr) {
       throw Error("assertion failed");
     }
-    emsc.hash_context_read(this.hashContextPtr, obj.nativePtr, obj.size());
+    emsc().funcs.hash_context_read(this.hashContextPtr, obj.nativePtr, 
obj.size());
   }
 
   /**
@@ -173,7 +272,7 @@ export class HashContext implements ArenaObject {
       throw Error("assertion failed");
     }
     h.alloc();
-    emsc.hash_context_finish(this.hashContextPtr, h.nativePtr);
+    emsc().funcs.hash_context_finish(this.hashContextPtr, h.nativePtr);
   }
 
   /**
@@ -181,7 +280,7 @@ export class HashContext implements ArenaObject {
    */
   destroy(): void {
     if (this.hashContextPtr) {
-      emsc.hash_context_abort(this.hashContextPtr);
+      emsc().funcs.hash_context_abort(this.hashContextPtr);
     }
     this.hashContextPtr = undefined;
   }
@@ -201,7 +300,7 @@ abstract class MallocArenaObject implements ArenaObject {
 
   destroy(): void {
     if (this._nativePtr && !this.isWeak) {
-      emsc.free(this.nativePtr);
+      emsc().funcs.free(this.nativePtr);
       this._nativePtr = undefined;
     }
   }
@@ -220,7 +319,7 @@ abstract class MallocArenaObject implements ArenaObject {
     if (this._nativePtr !== undefined) {
       throw Error("Double allocation");
     }
-    this.nativePtr = emscAlloc.malloc(size);
+    this.nativePtr = emsc().allocFuncs.malloc(size);
   }
 
   set nativePtr(v: number) {
@@ -314,18 +413,18 @@ export class Amount extends MallocArenaObject {
   constructor(args?: AmountJson, arena?: Arena) {
     super(arena);
     if (args) {
-      this.nativePtr = emscAlloc.get_amount(args.value,
+      this.nativePtr = emsc().allocFuncs.get_amount(args.value,
                                             0,
                                             args.fraction,
                                             args.currency);
     } else {
-      this.nativePtr = emscAlloc.get_amount(0, 0, 0, "");
+      this.nativePtr = emsc().allocFuncs.get_amount(0, 0, 0, "");
     }
   }
 
   static getZero(currency: string, a?: Arena): Amount {
     const am = new Amount(undefined, a);
-    const r = emsc.amount_get_zero(currency, am.nativePtr);
+    const r = emsc().funcs.amount_get_zero(currency, am.nativePtr);
     if (r !== GNUNET_OK) {
       throw Error("invalid currency");
     }
@@ -336,31 +435,31 @@ export class Amount extends MallocArenaObject {
   toNbo(a?: Arena): AmountNbo {
     const x = new AmountNbo(a);
     x.alloc();
-    emsc.amount_hton(x.nativePtr, this.nativePtr);
+    emsc().funcs.amount_hton(x.nativePtr, this.nativePtr);
     return x;
   }
 
   fromNbo(nbo: AmountNbo): void {
-    emsc.amount_ntoh(this.nativePtr, nbo.nativePtr);
+    emsc().funcs.amount_ntoh(this.nativePtr, nbo.nativePtr);
   }
 
   get value() {
-    return emsc.get_value(this.nativePtr);
+    return emsc().funcs.get_value(this.nativePtr);
   }
 
   get fraction() {
-    return emsc.get_fraction(this.nativePtr);
+    return emsc().funcs.get_fraction(this.nativePtr);
   }
 
   get currency(): string {
-    return emsc.get_currency(this.nativePtr);
+    return emsc().funcs.get_currency(this.nativePtr);
   }
 
   toJson(): AmountJson {
     return {
-      currency: emsc.get_currency(this.nativePtr),
-      fraction: emsc.get_fraction(this.nativePtr),
-      value: emsc.get_value(this.nativePtr),
+      currency: emsc().funcs.get_currency(this.nativePtr),
+      fraction: emsc().funcs.get_fraction(this.nativePtr),
+      value: emsc().funcs.get_value(this.nativePtr),
     };
   }
 
@@ -368,7 +467,7 @@ export class Amount extends MallocArenaObject {
    * Add an amount to this amount.
    */
   add(a: Amount) {
-    const res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr);
+    const res = emsc().funcs.amount_add(this.nativePtr, a.nativePtr, 
this.nativePtr);
     if (res < 1) {
       // Overflow
       return false;
@@ -381,7 +480,7 @@ export class Amount extends MallocArenaObject {
    */
   sub(a: Amount) {
     // this = this - a
-    const res = emsc.amount_subtract(this.nativePtr, this.nativePtr, 
a.nativePtr);
+    const res = emsc().funcs.amount_subtract(this.nativePtr, this.nativePtr, 
a.nativePtr);
     if (res === 0) {
       // Underflow
       return false;
@@ -397,11 +496,11 @@ export class Amount extends MallocArenaObject {
     if (this.currency !== a.currency) {
       throw Error(`incomparable currencies (${this.currency} and 
${a.currency})`);
     }
-    return emsc.amount_cmp(this.nativePtr, a.nativePtr);
+    return emsc().funcs.amount_cmp(this.nativePtr, a.nativePtr);
   }
 
   normalize() {
-    emsc.amount_normalize(this.nativePtr);
+    emsc().funcs.amount_normalize(this.nativePtr);
   }
 }
 
@@ -443,13 +542,13 @@ abstract class PackedArenaObject extends 
MallocArenaObject {
   }
 
   randomize(qual: RandomQuality = RandomQuality.STRONG): void {
-    emsc.random_block(qual, this.nativePtr, this.size());
+    emsc().funcs.random_block(qual, this.nativePtr, this.size());
   }
 
   toCrock(): string {
-    const d = emscAlloc.data_to_string_alloc(this.nativePtr, this.size());
-    const s = emscLib.Pointer_stringify(d);
-    emsc.free(d);
+    const d = emsc().allocFuncs.data_to_string_alloc(this.nativePtr, 
this.size());
+    const s = emsc().lib.Pointer_stringify(d);
+    emsc().funcs.free(d);
     return s;
   }
 
@@ -465,7 +564,7 @@ abstract class PackedArenaObject extends MallocArenaObject {
     // We need to get the javascript string
     // to the emscripten heap first.
     const buf = ByteArray.fromStringWithNull(s);
-    const res = emsc.string_to_data(buf.nativePtr,
+    const res = emsc().funcs.string_to_data(buf.nativePtr,
                                   s.length,
                                   this.nativePtr,
                                   this.size());
@@ -478,21 +577,21 @@ abstract class PackedArenaObject extends 
MallocArenaObject {
   alloc() {
     // FIXME: should the client be allowed to call alloc multiple times?
     if (!this._nativePtr) {
-      this.nativePtr = emscAlloc.malloc(this.size());
+      this.nativePtr = emsc().allocFuncs.malloc(this.size());
     }
   }
 
   hash(): HashCode {
     const x = new HashCode();
     x.alloc();
-    emsc.hash(this.nativePtr, this.size(), x.nativePtr);
+    emsc().funcs.hash(this.nativePtr, this.size(), x.nativePtr);
     return x;
   }
 
   hexdump() {
     const bytes: string[] = [];
     for (let i = 0; i < this.size(); i++) {
-      let b = emscLib.getValue(this.nativePtr + i, "i8");
+      let b = emsc().lib.getValue(this.nativePtr + i, "i8");
       b = (b + 256) % 256;
       bytes.push("0".concat(b.toString(16)).slice(-2));
     }
@@ -554,11 +653,11 @@ function fromCrockDecoded<T extends MallocArenaObject>(s: 
string,
  * Encode an object using a special encoding function.
  */
 function encode<T extends MallocArenaObject>(obj: T, encodeFn: any, arena?: 
Arena): ByteArray {
-  const ptr = emscAlloc.malloc(PTR_SIZE);
+  const ptr = emsc().allocFuncs.malloc(PTR_SIZE);
   const len = encodeFn(obj.nativePtr, ptr);
   const res = new ByteArray(len, undefined, arena);
-  res.nativePtr = emscLib.getValue(ptr, "*");
-  emsc.free(ptr);
+  res.nativePtr = emsc().lib.getValue(ptr, "*");
+  emsc().funcs.free(ptr);
   return res;
 }
 
@@ -569,7 +668,7 @@ function encode<T extends MallocArenaObject>(obj: T, 
encodeFn: any, arena?: Aren
 export class EddsaPrivateKey extends PackedArenaObject {
   static create(a?: Arena): EddsaPrivateKey {
     const obj = new EddsaPrivateKey(a);
-    obj.nativePtr = emscAlloc.eddsa_key_create();
+    obj.nativePtr = emsc().allocFuncs.eddsa_key_create();
     return obj;
   }
 
@@ -579,7 +678,7 @@ export class EddsaPrivateKey extends PackedArenaObject {
 
   getPublicKey(a?: Arena): EddsaPublicKey {
     const obj = new EddsaPublicKey(a);
-    obj.nativePtr = emscAlloc.eddsa_public_key_from_private(this.nativePtr);
+    obj.nativePtr = 
emsc().allocFuncs.eddsa_public_key_from_private(this.nativePtr);
     return obj;
   }
 
@@ -595,7 +694,7 @@ export class EddsaPrivateKey extends PackedArenaObject {
 export class EcdsaPrivateKey extends PackedArenaObject {
   static create(a?: Arena): EcdsaPrivateKey {
     const obj = new EcdsaPrivateKey(a);
-    obj.nativePtr = emscAlloc.ecdsa_key_create();
+    obj.nativePtr = emsc().allocFuncs.ecdsa_key_create();
     return obj;
   }
 
@@ -605,7 +704,7 @@ export class EcdsaPrivateKey extends PackedArenaObject {
 
   getPublicKey(a?: Arena): EcdsaPublicKey {
     const obj = new EcdsaPublicKey(a);
-    obj.nativePtr = emscAlloc.ecdsa_public_key_from_private(this.nativePtr);
+    obj.nativePtr = 
emsc().allocFuncs.ecdsa_public_key_from_private(this.nativePtr);
     return obj;
   }
 
@@ -621,7 +720,7 @@ export class EcdsaPrivateKey extends PackedArenaObject {
 export class EcdhePrivateKey extends PackedArenaObject {
   static create(a?: Arena): EcdhePrivateKey {
     const obj = new EcdhePrivateKey(a);
-    obj.nativePtr = emscAlloc.ecdhe_key_create();
+    obj.nativePtr = emsc().allocFuncs.ecdhe_key_create();
     return obj;
   }
 
@@ -631,7 +730,7 @@ export class EcdhePrivateKey extends PackedArenaObject {
 
   getPublicKey(a?: Arena): EcdhePublicKey {
     const obj = new EcdhePublicKey(a);
-    obj.nativePtr = emscAlloc.ecdhe_public_key_from_private(this.nativePtr);
+    obj.nativePtr = 
emsc().allocFuncs.ecdhe_public_key_from_private(this.nativePtr);
     return obj;
   }
 
@@ -728,7 +827,7 @@ export class HashCode extends PackedArenaObject {
 
   random(qual: RandomQuality = RandomQuality.STRONG) {
     this.alloc();
-    emsc.hash_create_random(qual, this.nativePtr);
+    emsc().funcs.hash_create_random(qual, this.nativePtr);
   }
 }
 
@@ -746,7 +845,7 @@ export class ByteArray extends PackedArenaObject {
   constructor(desiredSize: number, init?: number, a?: Arena) {
     super(a);
     if (init === undefined) {
-      this.nativePtr = emscAlloc.malloc(desiredSize);
+      this.nativePtr = emsc().allocFuncs.malloc(desiredSize);
     } else {
       this.nativePtr = init;
     }
@@ -756,16 +855,16 @@ export class ByteArray extends PackedArenaObject {
   static fromStringWithoutNull(s: string, a?: Arena): ByteArray {
     // UTF-8 bytes, including 0-terminator
     const terminatedByteLength = countUtf8Bytes(s) + 1;
-    const hstr = emscAlloc.malloc(terminatedByteLength);
-    emscLib.stringToUTF8(s, hstr, terminatedByteLength);
+    const hstr = emsc().allocFuncs.malloc(terminatedByteLength);
+    emsc().lib.stringToUTF8(s, hstr, terminatedByteLength);
     return new ByteArray(terminatedByteLength - 1, hstr, a);
   }
 
   static fromStringWithNull(s: string, a?: Arena): ByteArray {
     // UTF-8 bytes, including 0-terminator
     const terminatedByteLength = countUtf8Bytes(s) + 1;
-    const hstr = emscAlloc.malloc(terminatedByteLength);
-    emscLib.stringToUTF8(s, hstr, terminatedByteLength);
+    const hstr = emsc().allocFuncs.malloc(terminatedByteLength);
+    emsc().lib.stringToUTF8(s, hstr, terminatedByteLength);
     return new ByteArray(terminatedByteLength, hstr, a);
   }
 
@@ -773,12 +872,12 @@ export class ByteArray extends PackedArenaObject {
     // this one is a bit more complicated than the other fromCrock functions,
     // since we don't have a fixed size
     const byteLength = countUtf8Bytes(s);
-    const hstr = emscAlloc.malloc(byteLength + 1);
-    emscLib.stringToUTF8(s, hstr, byteLength + 1);
+    const hstr = emsc().allocFuncs.malloc(byteLength + 1);
+    emsc().lib.stringToUTF8(s, hstr, byteLength + 1);
     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);
+    const res = emsc().funcs.string_to_data(hstr, byteLength, ba.nativePtr, 
decodedLen);
+    emsc().funcs.free(hstr);
     if (res !== GNUNET_OK) {
       throw Error("decoding failed");
     }
@@ -802,9 +901,9 @@ export class EccSignaturePurpose extends PackedArenaObject {
               payload: PackedArenaObject,
               a?: Arena) {
     super(a);
-    this.nativePtr = emscAlloc.purpose_create(purpose,
-                                              payload.nativePtr,
-                                              payload.size());
+    this.nativePtr = emsc().allocFuncs.purpose_create(purpose,
+                                                      payload.nativePtr,
+                                                      payload.size());
     this.payloadSize = payload.size();
   }
 }
@@ -834,13 +933,13 @@ abstract class SignatureStruct {
       totalSize += member.size();
     }
 
-    const buf = emscAlloc.malloc(totalSize);
+    const buf = emsc().allocFuncs.malloc(totalSize);
     let ptr = buf;
     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);
+      emsc().funcs.memmove(ptr, member.nativePtr, size);
       ptr += size;
     }
     const ba = new ByteArray(totalSize, buf, a);
@@ -1081,7 +1180,7 @@ export class AbsoluteTimeNbo extends PackedArenaObject {
 // XXX: This only works up to 54 bit numbers.
 function set64(p: number, n: number) {
   for (let i = 0; i < 8; ++i) {
-    emscLib.setValue(p + (7 - i), n & 0xFF, "i8");
+    emsc().lib.setValue(p + (7 - i), n & 0xFF, "i8");
     n = Math.floor(n / 256);
   }
 }
@@ -1089,7 +1188,7 @@ function set64(p: number, n: number) {
 // XXX: This only works up to 54 bit numbers.
 function set32(p: number, n: number) {
   for (let i = 0; i < 4; ++i) {
-    emscLib.setValue(p + (3 - i), n & 0xFF, "i8");
+    emsc().lib.setValue(p + (3 - i), n & 0xFF, "i8");
     n = Math.floor(n / 256);
   }
 }
@@ -1273,11 +1372,47 @@ 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 {
   static fromCrock(s: string): RsaPublicKey {
-    return fromCrockDecoded(s, this, emscAlloc.rsa_public_key_decode);
+    return fromCrockDecoded(s, this, emsc().allocFuncs.rsa_public_key_decode);
   }
 
   toCrock() {
@@ -1285,12 +1420,12 @@ export class RsaPublicKey extends MallocArenaObject {
   }
 
   destroy() {
-    emsc.rsa_public_key_free(this.nativePtr);
+    emsc().funcs.rsa_public_key_free(this.nativePtr);
     this.nativePtr = 0;
   }
 
   encode(arena?: Arena): ByteArray {
-    return encode(this, emscAlloc.rsa_public_key_encode);
+    return encode(this, emsc().allocFuncs.rsa_public_key_encode);
   }
 }
 
@@ -1313,15 +1448,15 @@ export class EddsaSignature extends PackedArenaObject {
  */
 export class RsaSignature extends MallocArenaObject {
   static fromCrock(s: string, a?: Arena) {
-    return fromCrockDecoded(s, this, emscAlloc.rsa_signature_decode);
+    return fromCrockDecoded(s, this, emsc().allocFuncs.rsa_signature_decode);
   }
 
   encode(arena?: Arena): ByteArray {
-    return encode(this, emscAlloc.rsa_signature_encode);
+    return encode(this, emsc().allocFuncs.rsa_signature_encode);
   }
 
   destroy() {
-    emsc.rsa_signature_free(this.nativePtr);
+    emsc().funcs.rsa_signature_free(this.nativePtr);
     this.nativePtr = 0;
   }
 }
@@ -1334,17 +1469,17 @@ export function rsaBlind(hashCode: HashCode,
                          blindingKey: RsaBlindingKeySecret,
                          pkey: RsaPublicKey,
                          arena?: Arena): ByteArray|null {
-  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);
-  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);
+  const buf_ptr_out = emsc().allocFuncs.malloc(PTR_SIZE);
+  const buf_size_out = emsc().allocFuncs.malloc(PTR_SIZE);
+  const res = emsc().allocFuncs.rsa_blind(hashCode.nativePtr,
+                                          blindingKey.nativePtr,
+                                          pkey.nativePtr,
+                                          buf_ptr_out,
+                                          buf_size_out);
+  const buf_ptr = emsc().lib.getValue(buf_ptr_out, "*");
+  const buf_size = emsc().lib.getValue(buf_size_out, "*");
+  emsc().funcs.free(buf_ptr_out);
+  emsc().funcs.free(buf_size_out);
   if (res !== GNUNET_OK) {
     // malicious key
     return null;
@@ -1361,7 +1496,7 @@ export function eddsaSign(purpose: EccSignaturePurpose,
                           a?: Arena): EddsaSignature {
   const sig = new EddsaSignature(a);
   sig.alloc();
-  const res = emsc.eddsa_sign(priv.nativePtr, purpose.nativePtr, 
sig.nativePtr);
+  const res = emsc().funcs.eddsa_sign(priv.nativePtr, purpose.nativePtr, 
sig.nativePtr);
   if (res < 1) {
     throw Error("EdDSA signing failed");
   }
@@ -1377,10 +1512,20 @@ export function eddsaVerify(purposeNum: number,
                             sig: EddsaSignature,
                             pub: EddsaPublicKey,
                             a?: Arena): boolean {
-  const r = emsc.eddsa_verify(purposeNum,
-                            verify.nativePtr,
-                            sig.nativePtr,
-                            pub.nativePtr);
+  const r = emsc().funcs.eddsa_verify(purposeNum,
+                                      verify.nativePtr,
+                                      sig.nativePtr,
+                                      pub.nativePtr);
+  return r === GNUNET_OK;
+}
+
+
+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;
 }
 
@@ -1393,9 +1538,9 @@ export function rsaUnblind(sig: RsaSignature,
                            pk: RsaPublicKey,
                            a?: Arena): RsaSignature {
   const x = new RsaSignature(a);
-  x.nativePtr = emscAlloc.rsa_unblind(sig.nativePtr,
-                                      bk.nativePtr,
-                                      pk.nativePtr);
+  x.nativePtr = emsc().allocFuncs.rsa_unblind(sig.nativePtr,
+                                              bk.nativePtr,
+                                              pk.nativePtr);
   return x;
 }
 
@@ -1424,13 +1569,23 @@ export function ecdhEddsa(priv: EcdhePrivateKey,
                           pub: EddsaPublicKey): HashCode {
   const h = new HashCode();
   h.alloc();
-  const res = emsc.ecdh_eddsa(priv.nativePtr, pub.nativePtr, h.nativePtr);
+  const res = emsc().funcs.ecdh_eddsa(priv.nativePtr, pub.nativePtr, 
h.nativePtr);
   if (res !== GNUNET_OK) {
     throw Error("ecdh_eddsa failed");
   }
   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.
@@ -1443,10 +1598,10 @@ export function setupFreshCoin(secretSeed: 
TransferSecretP,
   blindingKey.isWeak = true;
   const buf = new ByteArray(priv.size() + blindingKey.size());
 
-  emsc.setup_fresh_coin(secretSeed.nativePtr, coinIndex, buf.nativePtr);
+  emsc().funcs.setup_fresh_coin(secretSeed.nativePtr, coinIndex, 
buf.nativePtr);
 
   priv.nativePtr = buf.nativePtr;
   blindingKey.nativePtr = buf.nativePtr + priv.size();
 
-  return {priv, blindingKey};
+  return { priv, blindingKey };
 }
diff --git a/src/crypto/emscLoader.d.ts b/src/crypto/emscLoader.d.ts
index f62604ee..3ec4f4cf 100644
--- a/src/crypto/emscLoader.d.ts
+++ b/src/crypto/emscLoader.d.ts
@@ -15,7 +15,7 @@
  */
 
 
-declare function getLib(): EmscLib;
+declare function getLib(): Promise<{ lib: EmscLib }>;
 
 /**
  * Signature of the function that retrieves emscripten
@@ -44,6 +44,12 @@ interface EmscLib {
 
   stringToUTF8(s: string, addr: number, maxLength: number): void;
 
+  onRuntimeInitialized(f: () => void): void;
+
+  readBinary?: (filename: string) => Promise<ArrayBuffer>;
+
+  calledRun?: boolean;
+
   _free(ptr: number): void;
 
   _malloc(n: number): number;
diff --git a/src/crypto/emscLoader.js b/src/crypto/emscLoader.js
index ed866281..59437da4 100644
--- a/src/crypto/emscLoader.js
+++ b/src/crypto/emscLoader.js
@@ -24,6 +24,8 @@
  * the right way to load the library.
  */
 
+let cachedLib = undefined;
+
 /**
  * Load the taler emscripten lib.
  *
@@ -31,6 +33,11 @@
  * be globally available.  Inside node, require is used.
  */
 export function getLib() {
+  console.log("in getLib");
+  if (cachedLib) {
+    console.log("lib is cached");
+    return Promise.resolve({ lib: cachedLib });
+  }
   if (typeof require !== "undefined") {
     // Make sure that TypeScript doesn't try
     // to check the taler-emscripten-lib.
@@ -45,7 +52,8 @@ export function getLib() {
     const lib = indirectRequire("../../../emscripten/taler-emscripten-lib.js");
     g.importScripts = savedImportScripts;
     if (lib) {
-      return lib;
+      cachedLib = lib;
+      return Promise.resolve({ lib: cachedLib });
     }
     // When we're running as a webpack bundle, the above require might
     // have failed and returned 'undefined', so we try other ways to import.
@@ -57,7 +65,20 @@ export function getLib() {
     if (!self.TalerEmscriptenLib) {
       throw Error("can't import taler emscripten lib");
     }
-    return self.TalerEmscriptenLib
+    const locateFile = (path, scriptDir) => {
+      console.log("locating file", "path", path, "scriptDir", scriptDir);
+      // This is quite hacky and assumes that our scriptDir is dist/
+      return scriptDir + "../emscripten/" + path;
+    };
+    console.log("instantiating TalerEmscriptenLib");
+    const lib = self.TalerEmscriptenLib({ locateFile });
+    cachedLib = lib;
+    return new Promise((resolve, reject) => {
+      lib.then(mod => {
+        console.log("emscripten module fully loaded");
+        resolve({ lib: mod });
+      });
+    });
   }
 
   // Last resort, we don't have require, we're not running in a webworker.
@@ -66,7 +87,7 @@ export function getLib() {
 
   if (typeof window !== "undefined") {
     if (window.TalerEmscriptenLib) {
-      return TalerEmscriptenLib;
+      return Promise.resolve(TalerEmscriptenLib);
     }
     throw Error("Looks like running in browser, but TalerEmscriptenLib is not 
defined");
   }
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]