gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (e1369ff7 -> a5137c32)


From: gnunet
Subject: [taler-wallet-core] branch master updated (e1369ff7 -> a5137c32)
Date: Mon, 02 Dec 2019 18:13:06 +0100

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

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

    from e1369ff7 the giant refactoring: split wallet into multiple parts
     new b5ee6b7b pending operations WIP
     new a5137c32 rollup

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


Summary of changes:
 Makefile                        |   3 +
 package.json                    |   6 +-
 rollup.config.js                |  32 +++++++++
 src/android/index.ts            |  26 +++++--
 src/crypto/cryptoApi.ts         |   4 +-
 src/i18n/de.po                  | 106 ++++++++++++++---------------
 src/i18n/en-US.po               | 106 ++++++++++++++---------------
 src/i18n/fr.po                  | 106 ++++++++++++++---------------
 src/i18n/it.po                  | 106 ++++++++++++++---------------
 src/i18n/strings.ts             | 146 ++++++++++++++++++++--------------------
 src/i18n/sv.po                  | 106 ++++++++++++++---------------
 src/i18n/taler-wallet-webex.pot | 106 ++++++++++++++---------------
 src/util/asyncMemo.ts           |   4 +-
 src/util/promiseUtils.ts        |  21 ++++++
 src/util/query.ts               |  19 +++++-
 src/util/timer.ts               |   8 +++
 src/wallet-impl/balance.ts      |   6 +-
 src/wallet-impl/pay.ts          |  11 ++-
 src/wallet-impl/pending.ts      |  44 ++++++++----
 src/wallet-impl/reserves.ts     |   1 +
 src/wallet-impl/state.ts        |   1 +
 src/wallet-impl/withdraw.ts     | 138 ++++++++++++++++++++-----------------
 src/wallet.ts                   |  86 +++++++++++++++--------
 src/walletTypes.ts              |   1 +
 src/webex/wxBackend.ts          |   3 +
 yarn.lock                       | 108 +++++++++++++++++++++++++++++
 26 files changed, 790 insertions(+), 514 deletions(-)
 create mode 100644 rollup.config.js

diff --git a/Makefile b/Makefile
index 9372fe1b..4190b14d 100644
--- a/Makefile
+++ b/Makefile
@@ -94,6 +94,9 @@ endif
 watch: tsconfig.json
        ./node_modules/.bin/webpack --watch
 
+.PHONY: rollup
+rollup: tsc
+       ./node_modules/.bin/rollup -c
 
 # Create the node_modules directory for the android wallet
 package-android:
diff --git a/package.json b/package.json
index c87efd4f..285906da 100644
--- a/package.json
+++ b/package.json
@@ -25,9 +25,10 @@
     "emscripten/"
   ],
   "devDependencies": {
+    "@rollup/plugin-json": "^4.0.0",
+    "@types/chrome": "^0.0.91",
     "@types/react": "^16.4.0",
     "@types/react-dom": "^16.0.0",
-    "@types/chrome": "^0.0.91",
     "ava": "^2.4.0",
     "awesome-typescript-loader": "^5.2.1",
     "glob": "^7.1.1",
@@ -46,6 +47,9 @@
     "prettier": "^1.18.2",
     "react": "^16.8.5",
     "react-dom": "^16.8.5",
+    "rollup": "^1.27.8",
+    "rollup-plugin-commonjs": "^10.1.0",
+    "rollup-plugin-node-resolve": "^5.2.0",
     "structured-clone": "^0.2.2",
     "terser-webpack-plugin": "^2.2.1",
     "through2": "3.0.1",
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 00000000..8038b509
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,32 @@
+// rollup.config.js
+import commonjs from 'rollup-plugin-commonjs';
+import nodeResolve from 'rollup-plugin-node-resolve';
+import json from '@rollup/plugin-json';
+import builtins from 'builtin-modules'
+
+
+const walletCli = {
+  input: 'dist/node/headless/taler-wallet-cli.js',
+  output: {
+    file: 'dist/standalone/taler-wallet-cli.js',
+    format: 'cjs'
+  },
+  plugins: [
+    json(),
+
+    nodeResolve({
+      external: builtins,
+      preferBuiltins: true
+    }),
+
+    commonjs({
+      include: ['node_modules/**', 'dist/node/**'],
+      extensions: [ '.js' ],
+      ignoreGlobal: false,  // Default: false
+      sourceMap: false,
+      ignore: [ 'taler-wallet' ]
+    })
+  ]
+};
+
+export default [walletCli];
diff --git a/src/android/index.ts b/src/android/index.ts
index 6a29f794..71144176 100644
--- a/src/android/index.ts
+++ b/src/android/index.ts
@@ -26,12 +26,10 @@ import {
 } from "../headless/helpers";
 import { openPromise, OpenedPromise } from "../util/promiseUtils";
 import fs = require("fs");
-import axios from "axios";
 import { HttpRequestLibrary, HttpResponse } from "../util/http";
-import querystring = require("querystring");
 
 // @ts-ignore: special built-in module
-import akono = require("akono");
+//import akono = require("akono");
 
 export class AndroidHttpLib implements HttpRequestLibrary {
   useNfcTunnel: boolean = false;
@@ -102,7 +100,7 @@ export class AndroidHttpLib implements HttpRequestLibrary {
 
 export function installAndroidWalletListener() {
   // @ts-ignore
-  const sendMessage: (m: string) => void = akono.sendMessage;
+  const sendMessage: (m: string) => void = globalThis.__akono_sendMessage;
   if (typeof sendMessage !== "function") {
     const errMsg =
       "FATAL: cannot install android wallet listener: akono functions missing";
@@ -137,8 +135,12 @@ export function installAndroidWalletListener() {
           persistentStoragePath: msg.args.persistentStoragePath,
           httpLib: httpLib,
         };
-        maybeWallet = await getDefaultNodeWallet(walletArgs);
-        wp.resolve(maybeWallet);
+        const w = await getDefaultNodeWallet(walletArgs);
+        maybeWallet = w;
+        w.runLoopScheduledRetries().catch((e) => {
+          console.error("Error during wallet retry loop", e);
+        });
+        wp.resolve(w);
         result = true;
         break;
       }
@@ -147,9 +149,19 @@ export function installAndroidWalletListener() {
         result = await wallet.getBalances();
         break;
       }
+      case "getPendingOperations": {
+        const wallet = await wp.promise;
+        result = await wallet.getPendingOperations();
+        break;
+      }
       case "withdrawTestkudos": {
         const wallet = await wp.promise;
-        result = await withdrawTestBalance(wallet);
+        await withdrawTestBalance(wallet);
+        break;
+      }
+      case "getHistory": {
+        const wallet = await wp.promise;
+        result = await wallet.getHistory();
         break;
       }
       case "preparePay": {
diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts
index 5ef78771..2521b54e 100644
--- a/src/crypto/cryptoApi.ts
+++ b/src/crypto/cryptoApi.ts
@@ -28,7 +28,6 @@ import {
   CoinRecord,
   DenominationRecord,
   RefreshSessionRecord,
-  ReserveRecord,
   TipPlanchet,
   WireFee,
 } from "../dbTypes";
@@ -195,7 +194,7 @@ export class CryptoApi {
     };
     this.resetWorkerTimeout(ws);
     work.startTime = timer.performanceNow();
-    ws.w!.postMessage(msg);
+    setImmediate(() => ws.w!.postMessage(msg));
   }
 
   resetWorkerTimeout(ws: WorkerState) {
@@ -323,7 +322,6 @@ export class CryptoApi {
         if (ws.currentWorkItem !== null) {
           continue;
         }
-
         this.wake(ws, workItem);
         return;
       }
diff --git a/src/i18n/de.po b/src/i18n/de.po
index 0181420a..e559cc07 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, c-format
+msgid "Unknown Wire Detail"
+msgstr ""
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,77 +57,77 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, 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/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, fuzzy, c-format
 msgid "Confirm payment"
 msgstr "Bezahlung bestätigen"
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr "Saldo"
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr "Verlauf"
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr "Debug"
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, 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:263
+#: src/webex/pages/popup.tsx:260
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, 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:344
+#: src/webex/pages/popup.tsx:341
 #, 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:353
+#: src/webex/pages/popup.tsx:350
 #, fuzzy, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
@@ -115,17 +135,17 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:366
+#: src/webex/pages/popup.tsx:363
 #, 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:381
+#: src/webex/pages/popup.tsx:378
 #, 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:391
+#: src/webex/pages/popup.tsx:388
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
@@ -133,12 +153,12 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, fuzzy, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
@@ -146,22 +166,22 @@ msgstr ""
 "               möchte einen Vertrag über %2$s\n"
 "               mit Ihnen abschließen."
 
-#: src/webex/pages/popup.tsx:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
@@ -183,49 +203,49 @@ msgstr "Saldo"
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, c-format
 msgid "Chose different exchange provider"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, c-format
 msgid "Select %1$s"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -270,26 +290,6 @@ msgstr ""
 msgid "Deposit Fee"
 msgstr ""
 
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, c-format
-msgid "Unknown Wire Detail"
-msgstr ""
-
 #, fuzzy, c-format
 #~ msgid "Submitting payment"
 #~ msgstr "Bezahlung bestätigen"
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index fd4a9c98..a490b6dc 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, c-format
+msgid "Unknown Wire Detail"
+msgstr ""
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,122 +57,122 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:263
+#: src/webex/pages/popup.tsx:260
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:344
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:353
+#: src/webex/pages/popup.tsx:350
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:366
+#: src/webex/pages/popup.tsx:363
 #, c-format
 msgid "Withdrew %1$s from %2$s ( %3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:378
 #, c-format
 msgid "Paid %1$s to merchant %2$s.%3$s( %4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:388
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
@@ -174,49 +194,49 @@ msgstr ""
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, c-format
 msgid "Chose different exchange provider"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, c-format
 msgid "Select %1$s"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -261,26 +281,6 @@ msgstr ""
 msgid "Deposit Fee"
 msgstr ""
 
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, c-format
-msgid "Unknown Wire Detail"
-msgstr ""
-
 #, fuzzy
 #~ msgid "DEBUG: Your balance on %1$s is %2$s KUDO. Get more at %3$s"
 #~ msgstr "DEBUG: Your balance is %2$s KUDO on %1$s. Get more at %3$s"
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index bbc02869..63256d55 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, c-format
+msgid "Unknown Wire Detail"
+msgstr ""
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,122 +57,122 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:263
+#: src/webex/pages/popup.tsx:260
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:344
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:353
+#: src/webex/pages/popup.tsx:350
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:366
+#: src/webex/pages/popup.tsx:363
 #, c-format
 msgid "Withdrew %1$s from %2$s ( %3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:378
 #, c-format
 msgid "Paid %1$s to merchant %2$s.%3$s( %4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:388
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
@@ -174,49 +194,49 @@ msgstr ""
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, c-format
 msgid "Chose different exchange provider"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, c-format
 msgid "Select %1$s"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -260,23 +280,3 @@ msgstr ""
 #, c-format
 msgid "Deposit Fee"
 msgstr ""
-
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, c-format
-msgid "Unknown Wire Detail"
-msgstr ""
diff --git a/src/i18n/it.po b/src/i18n/it.po
index bbc02869..63256d55 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, c-format
+msgid "Unknown Wire Detail"
+msgstr ""
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,122 +57,122 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:263
+#: src/webex/pages/popup.tsx:260
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:344
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:353
+#: src/webex/pages/popup.tsx:350
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:366
+#: src/webex/pages/popup.tsx:363
 #, c-format
 msgid "Withdrew %1$s from %2$s ( %3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:378
 #, c-format
 msgid "Paid %1$s to merchant %2$s.%3$s( %4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:388
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
@@ -174,49 +194,49 @@ msgstr ""
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, c-format
 msgid "Chose different exchange provider"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, c-format
 msgid "Select %1$s"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -260,23 +280,3 @@ msgstr ""
 #, c-format
 msgid "Deposit Fee"
 msgstr ""
-
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, c-format
-msgid "Unknown Wire Detail"
-msgstr ""
diff --git a/src/i18n/strings.ts b/src/i18n/strings.ts
index 86de3d8b..65a1d3f9 100644
--- a/src/i18n/strings.ts
+++ b/src/i18n/strings.ts
@@ -24,6 +24,22 @@ strings['de'] = {
         "plural_forms": "nplurals=2; plural=(n != 1);",
         "lang": ""
       },
+      "Invalid Wire": [
+        null,
+        ""
+      ],
+      "Invalid Test Wire Detail": [
+        null,
+        ""
+      ],
+      "Test Wire Acct #%1$s on %2$s": [
+        null,
+        ""
+      ],
+      "Unknown Wire Detail": [
+        null,
+        ""
+      ],
       "Operation": [
         null,
         ""
@@ -207,7 +223,19 @@ strings['de'] = {
       "Deposit Fee": [
         null,
         ""
-      ],
+      ]
+    }
+  }
+};
+strings['en-US'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
       "Invalid Wire": [
         null,
         ""
@@ -223,19 +251,7 @@ strings['de'] = {
       "Unknown Wire Detail": [
         null,
         ""
-      ]
-    }
-  }
-};
-strings['en-US'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
-      "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": ""
-      },
+      ],
       "Operation": [
         null,
         ""
@@ -419,7 +435,19 @@ strings['en-US'] = {
       "Deposit Fee": [
         null,
         ""
-      ],
+      ]
+    }
+  }
+};
+strings['fr'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
       "Invalid Wire": [
         null,
         ""
@@ -435,19 +463,7 @@ strings['en-US'] = {
       "Unknown Wire Detail": [
         null,
         ""
-      ]
-    }
-  }
-};
-strings['fr'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
-      "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": ""
-      },
+      ],
       "Operation": [
         null,
         ""
@@ -631,7 +647,19 @@ strings['fr'] = {
       "Deposit Fee": [
         null,
         ""
-      ],
+      ]
+    }
+  }
+};
+strings['it'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
       "Invalid Wire": [
         null,
         ""
@@ -647,19 +675,7 @@ strings['fr'] = {
       "Unknown Wire Detail": [
         null,
         ""
-      ]
-    }
-  }
-};
-strings['it'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
-      "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": ""
-      },
+      ],
       "Operation": [
         null,
         ""
@@ -843,7 +859,19 @@ strings['it'] = {
       "Deposit Fee": [
         null,
         ""
-      ],
+      ]
+    }
+  }
+};
+strings['sv'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
       "Invalid Wire": [
         null,
         ""
@@ -858,20 +886,8 @@ strings['it'] = {
       ],
       "Unknown Wire Detail": [
         null,
-        ""
-      ]
-    }
-  }
-};
-strings['sv'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
-      "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": ""
-      },
+        "visa mer"
+      ],
       "Operation": [
         null,
         ""
@@ -1055,22 +1071,6 @@ strings['sv'] = {
       "Deposit Fee": [
         null,
         "Depostitions avgift"
-      ],
-      "Invalid Wire": [
-        null,
-        ""
-      ],
-      "Invalid Test Wire Detail": [
-        null,
-        ""
-      ],
-      "Test Wire Acct #%1$s on %2$s": [
-        null,
-        ""
-      ],
-      "Unknown Wire Detail": [
-        null,
-        "visa mer"
       ]
     }
   }
diff --git a/src/i18n/sv.po b/src/i18n/sv.po
index dd546b77..03eab67f 100644
--- a/src/i18n/sv.po
+++ b/src/i18n/sv.po
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, fuzzy, c-format
+msgid "Unknown Wire Detail"
+msgstr "visa mer"
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,124 +57,124 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, fuzzy, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr "Säljaren %1$s erbjuder följande:"
 
-#: src/webex/pages/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, 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/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, fuzzy, c-format
 msgid "The total price is %1$s."
 msgstr "Det totala priset är %1$s."
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, c-format
 msgid "Confirm payment"
 msgstr "Godkän betalning"
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr "Balans"
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr "Historia"
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, 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:263
+#: src/webex/pages/popup.tsx:260
 #, fuzzy, c-format
 msgid "%1$s incoming"
 msgstr "%1$s inkommande"
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:344
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:353
+#: src/webex/pages/popup.tsx:350
 #, 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:366
+#: src/webex/pages/popup.tsx:363
 #, c-format
 msgid "Withdrew %1$s from %2$s ( %3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:378
 #, c-format
 msgid "Paid %1$s to merchant %2$s.%3$s( %4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:388
 #, 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:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, 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:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr "plånboken"
@@ -176,51 +196,51 @@ msgstr "Avbryt"
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, fuzzy, c-format
 msgid "Chose different exchange provider"
 msgstr "Ändra tjänsteleverantörer"
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, fuzzy, c-format
 msgid "Select %1$s"
 msgstr "Välj %1$s"
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, fuzzy, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 "Du är på väg att ta ut\n"
 " %1$s från ditt bankkonto till din plånbok.\n"
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr "Acceptera avgifter och utbetala"
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -265,26 +285,6 @@ msgstr "Återhämtnings avgift"
 msgid "Deposit Fee"
 msgstr "Depostitions avgift"
 
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, fuzzy, c-format
-msgid "Unknown Wire Detail"
-msgstr "visa mer"
-
 #, c-format
 #~ msgid "help"
 #~ msgstr "hjälp"
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index bbc02869..63256d55 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -27,6 +27,26 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+#: src/util/wire.ts:38
+#, c-format
+msgid "Invalid Wire"
+msgstr ""
+
+#: src/util/wire.ts:43 src/util/wire.ts:46
+#, c-format
+msgid "Invalid Test Wire Detail"
+msgstr ""
+
+#: src/util/wire.ts:48
+#, c-format
+msgid "Test Wire Acct #%1$s on %2$s"
+msgstr ""
+
+#: src/util/wire.ts:50
+#, c-format
+msgid "Unknown Wire Detail"
+msgstr ""
+
 #: src/webex/pages/benchmark.tsx:57
 #, c-format
 msgid "Operation"
@@ -37,122 +57,122 @@ msgstr ""
 msgid "time (ms/op)"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:118
+#: src/webex/pages/pay.tsx:117
 #, c-format
 msgid "The merchant %1$s offers you to purchase:"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:124
+#: src/webex/pages/pay.tsx:123
 #, c-format
 msgid "The total price is %1$s (plus %2$s fees)."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:129
+#: src/webex/pages/pay.tsx:128
 #, c-format
 msgid "The total price is %1$s."
 msgstr ""
 
-#: src/webex/pages/pay.tsx:149
+#: src/webex/pages/pay.tsx:148
 #, c-format
 msgid "Retry"
 msgstr ""
 
-#: src/webex/pages/pay.tsx:158
+#: src/webex/pages/pay.tsx:157
 #, c-format
 msgid "Confirm payment"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:162
+#: src/webex/pages/popup.tsx:159
 #, c-format
 msgid "Balance"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:163
+#: src/webex/pages/popup.tsx:160
 #, c-format
 msgid "History"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:164
+#: src/webex/pages/popup.tsx:161
 #, c-format
 msgid "Debug"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:200
+#: src/webex/pages/popup.tsx:197
 #, c-format
 msgid "You have no balance to show. Need some %1$s getting started?"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:263
+#: src/webex/pages/popup.tsx:260
 #, c-format
 msgid "%1$s incoming"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:275
+#: src/webex/pages/popup.tsx:272
 #, c-format
 msgid "%1$s being spent"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:306
+#: src/webex/pages/popup.tsx:303
 #, c-format
 msgid "Error: could not retrieve balance information."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:335
+#: src/webex/pages/popup.tsx:332
 #, c-format
 msgid "Bank requested reserve (%1$s) for %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:344
+#: src/webex/pages/popup.tsx:341
 #, c-format
 msgid "Started to withdraw %1$s from %2$s (%3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:353
+#: src/webex/pages/popup.tsx:350
 #, c-format
 msgid "Merchant %1$s offered contract %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:366
+#: src/webex/pages/popup.tsx:363
 #, c-format
 msgid "Withdrew %1$s from %2$s ( %3$s)."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:381
+#: src/webex/pages/popup.tsx:378
 #, c-format
 msgid "Paid %1$s to merchant %2$s.%3$s( %4$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:391
+#: src/webex/pages/popup.tsx:388
 #, c-format
 msgid "Merchant %1$s gave a refund over %2$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:404
+#: src/webex/pages/popup.tsx:400
 #, c-format
 msgid "tip"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:408
+#: src/webex/pages/popup.tsx:404
 #, c-format
 msgid "Merchant %1$s gave a %2$s of %3$s."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:414
+#: src/webex/pages/popup.tsx:410
 #, c-format
 msgid "You did not accept the tip yet."
 msgstr ""
 
-#: src/webex/pages/popup.tsx:422
+#: src/webex/pages/popup.tsx:418
 #, c-format
 msgid "Unknown event (%1$s)"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:464
+#: src/webex/pages/popup.tsx:460
 #, c-format
 msgid "Error: could not retrieve event history"
 msgstr ""
 
-#: src/webex/pages/popup.tsx:489
+#: src/webex/pages/popup.tsx:485
 #, c-format
 msgid "Your wallet has no events recorded."
 msgstr ""
@@ -174,49 +194,49 @@ msgstr ""
 
 #. #-#-#-#-#  - (PACKAGE VERSION)  #-#-#-#-#
 #. TODO:generic error reporting function or component.
-#: src/webex/pages/tip.tsx:118 src/webex/pages/withdraw.tsx:216
+#: src/webex/pages/tip.tsx:116 src/webex/pages/withdraw.tsx:214
 #, c-format
 msgid "Fatal error: \"%1$s\"."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:73
+#: src/webex/pages/withdraw.tsx:72
 #, c-format
 msgid "Could not get details for withdraw operation:"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:89 src/webex/pages/withdraw.tsx:179
+#: src/webex/pages/withdraw.tsx:88 src/webex/pages/withdraw.tsx:178
 #, c-format
 msgid "Chose different exchange provider"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:108
+#: src/webex/pages/withdraw.tsx:107
 #, c-format
 msgid ""
 "Please select an exchange.  You can review the details before after your "
 "selection."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:120
+#: src/webex/pages/withdraw.tsx:119
 #, c-format
 msgid "Select %1$s"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:142
+#: src/webex/pages/withdraw.tsx:141
 #, c-format
 msgid "Select custom exchange"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:159
+#: src/webex/pages/withdraw.tsx:158
 #, c-format
 msgid "You are about to withdraw %1$s from your bank account into your wallet."
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:170
+#: src/webex/pages/withdraw.tsx:169
 #, c-format
 msgid "Accept fees and withdraw"
 msgstr ""
 
-#: src/webex/pages/withdraw.tsx:188
+#: src/webex/pages/withdraw.tsx:187
 #, c-format
 msgid "Cancel withdraw operation"
 msgstr ""
@@ -260,23 +280,3 @@ msgstr ""
 #, c-format
 msgid "Deposit Fee"
 msgstr ""
-
-#: src/wire.ts:38
-#, c-format
-msgid "Invalid Wire"
-msgstr ""
-
-#: src/wire.ts:43 src/wire.ts:46
-#, c-format
-msgid "Invalid Test Wire Detail"
-msgstr ""
-
-#: src/wire.ts:48
-#, c-format
-msgid "Test Wire Acct #%1$s on %2$s"
-msgstr ""
-
-#: src/wire.ts:50
-#, c-format
-msgid "Unknown Wire Detail"
-msgstr ""
diff --git a/src/util/asyncMemo.ts b/src/util/asyncMemo.ts
index 8b7b1c9b..34868ab4 100644
--- a/src/util/asyncMemo.ts
+++ b/src/util/asyncMemo.ts
@@ -21,8 +21,8 @@ export interface MemoEntry<T> {
 }
 
 export class AsyncOpMemo<T> {
-  n = 0;
-  memo: { [k: string]: MemoEntry<T> } = {};
+  private n = 0;
+  private memo: { [k: string]: MemoEntry<T> } = {};
   put(key: string, p: Promise<T>): Promise<T> {
     const n = this.n++;
     this.memo[key] = {
diff --git a/src/util/promiseUtils.ts b/src/util/promiseUtils.ts
index eb649471..9add2c40 100644
--- a/src/util/promiseUtils.ts
+++ b/src/util/promiseUtils.ts
@@ -36,4 +36,25 @@ export function openPromise<T>(): OpenedPromise<T> {
     throw Error();
   }
   return { resolve, reject, promise };
+}
+
+export class AsyncCondition {
+  private _waitPromise: Promise<void>;
+  private _resolveWaitPromise: (val: void) => void;
+  constructor() {
+    const op = openPromise<void>();
+    this._waitPromise = op.promise;
+    this._resolveWaitPromise = op.resolve;
+  }
+
+  wait(): Promise<void> {
+    return this._waitPromise;
+  }
+
+  trigger(): void {
+    this._resolveWaitPromise();
+    const op = openPromise<void>();
+    this._waitPromise = op.promise;
+    this._resolveWaitPromise = op.resolve;
+  }
 }
\ No newline at end of file
diff --git a/src/util/query.ts b/src/util/query.ts
index 5726bcaa..6942d471 100644
--- a/src/util/query.ts
+++ b/src/util/query.ts
@@ -351,15 +351,32 @@ class TransactionHandle {
   }
 }
 
+export function runWithReadTransaction<T>(
+  db: IDBDatabase,
+  stores: Store<any>[],
+  f: (t: TransactionHandle) => Promise<T>,
+): Promise<T> {
+  return runWithTransaction<T>(db, stores, f, "readonly");
+}
+
 export function runWithWriteTransaction<T>(
   db: IDBDatabase,
   stores: Store<any>[],
   f: (t: TransactionHandle) => Promise<T>,
+): Promise<T> {
+  return runWithTransaction<T>(db, stores, f, "readwrite");
+}
+
+function runWithTransaction<T>(
+  db: IDBDatabase,
+  stores: Store<any>[],
+  f: (t: TransactionHandle) => Promise<T>,
+  mode: "readonly" | "readwrite",
 ): Promise<T> {
   const stack = Error("Failed transaction was started here.");
   return new Promise((resolve, reject) => {
     const storeName = stores.map(x => x.name);
-    const tx = db.transaction(storeName, "readwrite");
+    const tx = db.transaction(storeName, mode);
     let funResult: any = undefined;
     let gotFunResult: boolean = false;
     tx.oncomplete = () => {
diff --git a/src/util/timer.ts b/src/util/timer.ts
index d3bb5d48..865c17fa 100644
--- a/src/util/timer.ts
+++ b/src/util/timer.ts
@@ -105,6 +105,14 @@ export class TimerGroup {
     }
   }
 
+  resolveAfter(delayMs: number): Promise<void> {
+    return new Promise<void>((resolve, reject) => {
+      this.after(delayMs, () => {
+        resolve();
+      });
+    });
+  }
+
   after(delayMs: number, callback: () => void): TimerHandle {
     if (this.stopped) {
       console.warn("dropping timer since timer group is stopped");
diff --git a/src/wallet-impl/balance.ts b/src/wallet-impl/balance.ts
index 1d8e077a..0abc9663 100644
--- a/src/wallet-impl/balance.ts
+++ b/src/wallet-impl/balance.ts
@@ -18,12 +18,10 @@
  * Imports.
  */
 import {
-  HistoryQuery,
-  HistoryEvent,
   WalletBalance,
   WalletBalanceEntry,
 } from "../walletTypes";
-import { oneShotIter, runWithWriteTransaction } from "../util/query";
+import { runWithReadTransaction } from "../util/query";
 import { InternalWalletState } from "./state";
 import { Stores, TipRecord, CoinStatus } from "../dbTypes";
 import * as Amounts from "../util/amounts";
@@ -77,7 +75,7 @@ export async function getBalances(
     byExchange: {},
   };
 
-  await runWithWriteTransaction(
+  await runWithReadTransaction(
     ws.db,
     [Stores.coins, Stores.refresh, Stores.reserves, Stores.purchases],
     async tx => {
diff --git a/src/wallet-impl/pay.ts b/src/wallet-impl/pay.ts
index d4d2b3cd..31a1500e 100644
--- a/src/wallet-impl/pay.ts
+++ b/src/wallet-impl/pay.ts
@@ -358,9 +358,14 @@ async function recordConfirmPay(
 }
 
 function getNextUrl(contractTerms: ContractTerms): string {
-  const fu = new URL(contractTerms.fulfillment_url)
-  fu.searchParams.set("order_id", contractTerms.order_id);
-  return fu.href;
+  const f = contractTerms.fulfillment_url;
+  if (f.startsWith("http://";) || f.startsWith("https://";)) {
+    const fu = new URL(contractTerms.fulfillment_url)
+    fu.searchParams.set("order_id", contractTerms.order_id);
+    return fu.href;
+  } else {
+    return f;
+  }
 }
 
 export async function abortFailedPayment(
diff --git a/src/wallet-impl/pending.ts b/src/wallet-impl/pending.ts
index a66571a3..dbc6672c 100644
--- a/src/wallet-impl/pending.ts
+++ b/src/wallet-impl/pending.ts
@@ -14,18 +14,29 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
- /**
-  * Imports.
-  */
-import { PendingOperationInfo, PendingOperationsResponse } from 
"../walletTypes";
+/**
+ * Imports.
+ */
+import {
+  PendingOperationInfo,
+  PendingOperationsResponse,
+  getTimestampNow,
+} from "../walletTypes";
 import { oneShotIter } from "../util/query";
 import { InternalWalletState } from "./state";
-import { Stores, ExchangeUpdateStatus, ReserveRecordStatus, CoinStatus, 
ProposalStatus } from "../dbTypes";
+import {
+  Stores,
+  ExchangeUpdateStatus,
+  ReserveRecordStatus,
+  CoinStatus,
+  ProposalStatus,
+} from "../dbTypes";
 
 export async function getPendingOperations(
   ws: InternalWalletState,
 ): Promise<PendingOperationsResponse> {
   const pendingOperations: PendingOperationInfo[] = [];
+  let minRetryDurationMs = 5000;
   const exchanges = await oneShotIter(ws.db, Stores.exchanges).toArray();
   for (let e of exchanges) {
     switch (e.updateStatus) {
@@ -92,9 +103,8 @@ export async function getPendingOperations(
     }
   }
   await oneShotIter(ws.db, Stores.reserves).forEach(reserve => {
-    const reserveType = reserve.bankWithdrawStatusUrl
-      ? "taler-bank"
-      : "manual";
+    const reserveType = reserve.bankWithdrawStatusUrl ? "taler-bank" : 
"manual";
+    const now = getTimestampNow();
     switch (reserve.reserveStatus) {
       case ReserveRecordStatus.DORMANT:
         // nothing to report as pending
@@ -110,6 +120,11 @@ export async function getPendingOperations(
           reserveType,
           reservePub: reserve.reservePub,
         });
+        if (reserve.created.t_ms < now.t_ms - 5000) {
+          minRetryDurationMs = 500;
+        } else if (reserve.created.t_ms < now.t_ms - 30000) {
+          minRetryDurationMs = 2000;
+        }
         break;
       case ReserveRecordStatus.WAIT_CONFIRM_BANK:
         pendingOperations.push({
@@ -120,6 +135,11 @@ export async function getPendingOperations(
           reservePub: reserve.reservePub,
           bankWithdrawConfirmUrl: reserve.bankWithdrawConfirmUrl,
         });
+        if (reserve.created.t_ms < now.t_ms - 5000) {
+          minRetryDurationMs = 500;
+        } else if (reserve.created.t_ms < now.t_ms - 30000) {
+          minRetryDurationMs = 2000;
+        }
         break;
       default:
         pendingOperations.push({
@@ -164,10 +184,7 @@ export async function getPendingOperations(
   });
 
   await oneShotIter(ws.db, Stores.withdrawalSession).forEach(ws => {
-    const numCoinsWithdrawn = ws.withdrawn.reduce(
-      (a, x) => a + (x ? 1 : 0),
-      0,
-    );
+    const numCoinsWithdrawn = ws.withdrawn.reduce((a, x) => a + (x ? 1 : 0), 
0);
     const numCoinsTotal = ws.withdrawn.length;
     if (numCoinsWithdrawn < numCoinsTotal) {
       pendingOperations.push({
@@ -204,5 +221,8 @@ export async function getPendingOperations(
 
   return {
     pendingOperations,
+    nextRetryDelay: {
+      d_ms: minRetryDurationMs,
+    },
   };
 }
diff --git a/src/wallet-impl/reserves.ts b/src/wallet-impl/reserves.ts
index 265eddce..5d624fe2 100644
--- a/src/wallet-impl/reserves.ts
+++ b/src/wallet-impl/reserves.ts
@@ -105,6 +105,7 @@ export async function createReserve(
   const exchangeInfo = await updateExchangeFromUrl(ws, req.exchange);
   const exchangeDetails = exchangeInfo.details;
   if (!exchangeDetails) {
+    console.log(exchangeDetails);
     throw Error("exchange not updated");
   }
   const { isAudited, isTrusted } = await getExchangeTrust(ws, exchangeInfo);
diff --git a/src/wallet-impl/state.ts b/src/wallet-impl/state.ts
index 3d6bb8bd..a04a7dd1 100644
--- a/src/wallet-impl/state.ts
+++ b/src/wallet-impl/state.ts
@@ -29,4 +29,5 @@ export interface InternalWalletState {
   speculativePayData: SpeculativePayData | undefined;
   cachedNextUrl: { [fulfillmentUrl: string]: NextUrlResult };
   memoProcessReserve: AsyncOpMemo<void>;
+  memoMakePlanchet: AsyncOpMemo<void>;
 }
\ No newline at end of file
diff --git a/src/wallet-impl/withdraw.ts b/src/wallet-impl/withdraw.ts
index 4e2d8055..baeae1a5 100644
--- a/src/wallet-impl/withdraw.ts
+++ b/src/wallet-impl/withdraw.ts
@@ -189,7 +189,6 @@ async function processPlanchet(
     return;
   }
   if (withdrawalSession.source.type === "reserve") {
-
   }
   const planchet = withdrawalSession.planchets[coinIdx];
   if (!planchet) {
@@ -251,10 +250,7 @@ async function processPlanchet(
     ws.db,
     [Stores.coins, Stores.withdrawalSession, Stores.reserves],
     async tx => {
-      const ws = await tx.get(
-        Stores.withdrawalSession,
-        withdrawalSessionId,
-      );
+      const ws = await tx.get(Stores.withdrawalSession, withdrawalSessionId);
       if (!ws) {
         return;
       }
@@ -350,12 +346,72 @@ export async function getVerifiedWithdrawDenomList(
   return selectedDenoms;
 }
 
+async function makePlanchet(
+  ws: InternalWalletState,
+  withdrawalSessionId: string,
+  coinIndex: number,
+): Promise<void> {
+  const withdrawalSession = await oneShotGet(
+    ws.db,
+    Stores.withdrawalSession,
+    withdrawalSessionId,
+  );
+  if (!withdrawalSession) {
+    return;
+  }
+  const src = withdrawalSession.source;
+  if (src.type !== "reserve") {
+    throw Error("invalid state");
+  }
+  const reserve = await oneShotGet(ws.db, Stores.reserves, src.reservePub);
+  if (!reserve) {
+    return;
+  }
+  const denom = await oneShotGet(ws.db, Stores.denominations, [
+    withdrawalSession.exchangeBaseUrl,
+    withdrawalSession.denoms[coinIndex],
+  ]);
+  if (!denom) {
+    return;
+  }
+  const r = await ws.cryptoApi.createPlanchet({
+    denomPub: denom.denomPub,
+    feeWithdraw: denom.feeWithdraw,
+    reservePriv: reserve.reservePriv,
+    reservePub: reserve.reservePub,
+    value: denom.value,
+  });
+  const newPlanchet: PlanchetRecord = {
+    blindingKey: r.blindingKey,
+    coinEv: r.coinEv,
+    coinPriv: r.coinPriv,
+    coinPub: r.coinPub,
+    coinValue: r.coinValue,
+    denomPub: r.denomPub,
+    denomPubHash: r.denomPubHash,
+    isFromTip: false,
+    reservePub: r.reservePub,
+    withdrawSig: r.withdrawSig,
+  };
+  await runWithWriteTransaction(ws.db, [Stores.withdrawalSession], async tx => 
{
+    const myWs = await tx.get(Stores.withdrawalSession, withdrawalSessionId);
+    if (!myWs) {
+      return;
+    }
+    if (myWs.planchets[coinIndex]) {
+      return;
+    }
+    myWs.planchets[coinIndex] = newPlanchet;
+    await tx.put(Stores.withdrawalSession, myWs);
+  });
+}
+
 async function processWithdrawCoin(
   ws: InternalWalletState,
   withdrawalSessionId: string,
   coinIndex: number,
 ) {
-  logger.info("starting withdraw for coin");
+  logger.trace("starting withdraw for coin", coinIndex);
   const withdrawalSession = await oneShotGet(
     ws.db,
     Stores.withdrawalSession,
@@ -377,63 +433,23 @@ async function processWithdrawCoin(
     return;
   }
 
-  if (withdrawalSession.planchets[coinIndex]) {
-    return processPlanchet(ws, withdrawalSessionId, coinIndex);
-  } else {
-    const src = withdrawalSession.source;
-    if (src.type !== "reserve") {
-      throw Error("invalid state");
-    }
-    const reserve = await oneShotGet(ws.db, Stores.reserves, src.reservePub)
-    if (!reserve) {
-      return;
-    }
-    const denom = await oneShotGet(ws.db, Stores.denominations, [
-      withdrawalSession.exchangeBaseUrl,
-      withdrawalSession.denoms[coinIndex],
-    ]);
-    if (!denom) {
-      return;
+  if (!withdrawalSession.planchets[coinIndex]) {
+    logger.trace("creating planchet for coin", coinIndex);
+    const key = `${withdrawalSessionId}-${coinIndex}`;
+    const p = ws.memoMakePlanchet.find(key);
+    if (p) {
+      await p;
+    } else {
+      ws.memoMakePlanchet.put(
+        key,
+        makePlanchet(ws, withdrawalSessionId, coinIndex),
+      );
     }
-    const r = await ws.cryptoApi.createPlanchet({
-      denomPub: denom.denomPub,
-      feeWithdraw: denom.feeWithdraw,
-      reservePriv: reserve.reservePriv,
-      reservePub: reserve.reservePub,
-      value: denom.value,
-    });
-    const newPlanchet: PlanchetRecord = {
-      blindingKey: r.blindingKey,
-      coinEv: r.coinEv,
-      coinPriv: r.coinPriv,
-      coinPub: r.coinPub,
-      coinValue: r.coinValue,
-      denomPub: r.denomPub,
-      denomPubHash: r.denomPubHash,
-      isFromTip: false,
-      reservePub: r.reservePub,
-      withdrawSig: r.withdrawSig,
-    };
-    await runWithWriteTransaction(
-      ws.db,
-      [Stores.withdrawalSession],
-      async tx => {
-        const myWs = await tx.get(
-          Stores.withdrawalSession,
-          withdrawalSessionId,
-        );
-        if (!myWs) {
-          return;
-        }
-        if (myWs.planchets[coinIndex]) {
-          return;
-        }
-        myWs.planchets[coinIndex] = newPlanchet;
-        await tx.put(Stores.withdrawalSession, myWs);
-      },
-    );
-    await processPlanchet(ws, withdrawalSessionId, coinIndex);
+    await makePlanchet(ws, withdrawalSessionId, coinIndex);
+    logger.trace("done creating planchet for coin", coinIndex);
   }
+  await processPlanchet(ws, withdrawalSessionId, coinIndex);
+  logger.trace("starting withdraw for coin", coinIndex);
 }
 
 export async function processWithdrawSession(
diff --git a/src/wallet.ts b/src/wallet.ts
index 91f6c0cc..a6eecb8a 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -46,7 +46,6 @@ import {
   abortFailedPayment,
   preparePay,
   confirmPay,
-  SpeculativePayData,
 } from "./wallet-impl/pay";
 
 import {
@@ -55,7 +54,6 @@ import {
   CurrencyRecord,
   DenominationRecord,
   ExchangeRecord,
-  PlanchetRecord,
   ProposalRecord,
   PurchaseRecord,
   ReserveRecord,
@@ -107,9 +105,11 @@ import { processWithdrawSession } from 
"./wallet-impl/withdraw";
 import { getHistory } from "./wallet-impl/history";
 import { getPendingOperations } from "./wallet-impl/pending";
 import { getBalances } from "./wallet-impl/balance";
-import { acceptTip, getTipStatus } from "./wallet-impl/tip";
+import { acceptTip, getTipStatus, processTip } from "./wallet-impl/tip";
 import { returnCoins } from "./wallet-impl/return";
 import { payback } from "./wallet-impl/payback";
+import { TimerGroup } from "./util/timer";
+import { AsyncCondition } from "./util/promiseUtils";
 
 /**
  * Wallet protocol version spoken with the exchange
@@ -155,6 +155,9 @@ const logger = new Logger("wallet.ts");
  */
 export class Wallet {
   private ws: InternalWalletState;
+  private timerGroup: TimerGroup = new TimerGroup();
+  private latch = new AsyncCondition();
+  private stopped: boolean = false;
 
   get db(): IDBDatabase {
     return this.ws.db;
@@ -188,6 +191,7 @@ export class Wallet {
       notifier,
       speculativePayData: undefined,
       memoProcessReserve: new AsyncOpMemo<void>(),
+      memoMakePlanchet: new AsyncOpMemo<void>(),
     };
   }
 
@@ -195,7 +199,6 @@ export class Wallet {
     return getExchangePaytoUri(this.ws, exchangeBaseUrl, supportedTargetTypes);
   }
 
-
   getWithdrawDetailsForAmount(baseUrl: any, amount: AmountJson): any {
     return getWithdrawDetailsForAmount(this.ws, baseUrl, amount);
   }
@@ -210,26 +213,26 @@ export class Wallet {
       case "bug":
         return;
       case "dirty-coin":
-        await this.refresh(pending.coinPub);
+        await refresh(this.ws, pending.coinPub);
         break;
       case "exchange-update":
-        await this.updateExchangeFromUrl(pending.exchangeBaseUrl);
-        break;
-      case "planchet":
-        // Nothing to do, since the withdraw session will process the planchet
+        await updateExchangeFromUrl(this.ws, pending.exchangeBaseUrl);
         break;
       case "refresh":
-        await this.processRefreshSession(pending.refreshSessionId);
+        await processRefreshSession(this.ws, pending.refreshSessionId);
         break;
       case "reserve":
-        await this.processReserve(pending.reservePub);
+        await processReserve(this.ws, pending.reservePub);
         break;
       case "withdraw":
-        await this.processWithdrawSession(pending.withdrawSessionId);
+        await processWithdrawSession(this.ws, pending.withdrawSessionId);
         break;
       case "proposal":
         // Nothing to do, user needs to accept/reject
         break;
+      case "tip":
+        await processTip(this.ws, pending.tipId);
+        break;
       default:
         assertUnreachable(pending);
     }
@@ -253,8 +256,22 @@ export class Wallet {
    * Process pending operations and wait for scheduled operations in
    * a loop until the wallet is stopped explicitly.
    */
-  public async runUntilStopped(): Promise<void> {
-    throw Error("not implemented");
+  public async runLoopScheduledRetries(): Promise<void> {
+    while (!this.stopped) {
+      console.log("running wallet retry loop iteration");
+      let pending = await this.getPendingOperations();
+      console.log("waiting for", pending.nextRetryDelay);
+      const timeout = 
this.timerGroup.resolveAfter(pending.nextRetryDelay.d_ms);
+      await Promise.race([timeout, this.latch.wait()]);
+      pending = await this.getPendingOperations();
+      for (const p of pending.pendingOperations) {
+        try {
+          this.processOnePendingOperation(p);
+        } catch (e) {
+          console.error(e);
+        }
+      }
+    }
   }
 
   /**
@@ -267,9 +284,12 @@ export class Wallet {
       const allPending = r.pendingOperations;
       const relevantPending = allPending.filter(x => {
         switch (x.type) {
-          case "planchet":
           case "reserve":
             return x.reservePub === reservePub;
+          case "withdraw":
+            return (
+              x.source.type === "reserve" && x.source.reservePub === reservePub
+            );
           default:
             return false;
         }
@@ -347,7 +367,11 @@ export class Wallet {
     proposalId: string,
     sessionIdOverride: string | undefined,
   ): Promise<ConfirmPayResult> {
-    return confirmPay(this.ws, proposalId, sessionIdOverride);
+    try {
+      return await confirmPay(this.ws, proposalId, sessionIdOverride);
+    } finally {
+      this.latch.trigger();
+    }
   }
 
   /**
@@ -358,7 +382,11 @@ export class Wallet {
    * state DORMANT.
    */
   async processReserve(reservePub: string): Promise<void> {
-    return processReserve(this.ws, reservePub);
+    try {
+      return await processReserve(this.ws, reservePub);
+    } finally {
+      this.latch.trigger();
+    }
   }
 
   /**
@@ -370,7 +398,11 @@ export class Wallet {
   async createReserve(
     req: CreateReserveRequest,
   ): Promise<CreateReserveResponse> {
-    return createReserve(this.ws, req);
+    try {
+      return createReserve(this.ws, req);
+    } finally {
+      this.latch.trigger();
+    }
   }
 
   /**
@@ -383,14 +415,13 @@ export class Wallet {
    * an unconfirmed reserve should be hidden.
    */
   async confirmReserve(req: ConfirmReserveRequest): Promise<void> {
-    return confirmReserve(this.ws, req);
+    try {
+      return confirmReserve(this.ws, req);
+    } finally {
+      this.latch.trigger();
+    }
   }
 
-  private async processWithdrawSession(
-    withdrawalSessionId: string,
-  ): Promise<void> {
-    return processWithdrawSession(this.ws, withdrawalSessionId);
-  }
 
   /**
    * Check if and how an exchange is trusted and/or audited.
@@ -435,10 +466,6 @@ export class Wallet {
     return refresh(this.ws, oldCoinPub, force);
   }
 
-  async processRefreshSession(refreshSessionId: string) {
-    return processRefreshSession(this.ws, refreshSessionId);
-  }
-
   async findExchange(
     exchangeBaseUrl: string,
   ): Promise<ExchangeRecord | undefined> {
@@ -516,7 +543,8 @@ export class Wallet {
    * Stop ongoing processing.
    */
   stop() {
-    //this.timerGroup.stopCurrentAndFutureTimers();
+    this.stopped = true;
+    this.timerGroup.stopCurrentAndFutureTimers();
     this.cryptoApi.stop();
   }
 
diff --git a/src/walletTypes.ts b/src/walletTypes.ts
index 5736282e..b12b29c5 100644
--- a/src/walletTypes.ts
+++ b/src/walletTypes.ts
@@ -609,6 +609,7 @@ export type PendingOperationInfo =
 
 export interface PendingOperationsResponse {
   pendingOperations: PendingOperationInfo[];
+  nextRetryDelay: Duration;
 }
 
 export interface HistoryQuery {
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 2d7f963e..752027b7 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -467,6 +467,9 @@ async function reinitWallet() {
     notifier,
     new BrowserCryptoWorkerFactory(),
   );
+  wallet.runLoopScheduledRetries().catch((e) => {
+    console.log("error during wallet retry loop", e);
+  });
   // Useful for debugging in the background page.
   (window as any).talerWallet = wallet;
   currentWallet = wallet;
diff --git a/yarn.lock b/yarn.lock
index a28bb07c..74d331dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -309,6 +309,13 @@
     "@nodelib/fs.scandir" "2.1.3"
     fastq "^1.6.0"
 
+"@rollup/plugin-json@^4.0.0":
+  version "4.0.0"
+  resolved 
"https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.0.0.tgz#4462e83c7ad5544bef4a601a6e8450daedc4b69b";
+  integrity 
sha512-Z65CtEVWv40+ri4CvmswyhtuUtki9yP5p0UJN/GyCKKyU4jRuDS9CG0ZuV7/XuS7zGkoajyE7E4XBEaC4GW62A==
+  dependencies:
+    rollup-pluginutils "^2.5.0"
+
 "@sindresorhus/is@^0.14.0":
   version "0.14.0"
   resolved 
"https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea";
@@ -333,6 +340,16 @@
   resolved 
"https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0";
   integrity 
sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
 
+"@types/estree@*":
+  version "0.0.40"
+  resolved 
"https://registry.yarnpkg.com/@types/estree/-/estree-0.0.40.tgz#0e6cb9b9bbd098031fa19e4b4e8131bc70e5de13";
+  integrity 
sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==
+
+"@types/estree@0.0.39":
+  version "0.0.39"
+  resolved 
"https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f";
+  integrity 
sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
+
 "@types/events@*":
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7";
@@ -394,6 +411,13 @@
     "@types/prop-types" "*"
     csstype "^2.2.0"
 
+"@types/resolve@0.0.8":
+  version "0.0.8"
+  resolved 
"https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194";
+  integrity 
sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
+  dependencies:
+    "@types/node" "*"
+
 "@webassemblyjs/ast@1.8.5":
   version "1.8.5"
   resolved 
"https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359";
@@ -573,6 +597,11 @@ acorn@^6.0.7, acorn@^6.2.1:
   resolved 
"https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e";
   integrity 
sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
 
+acorn@^7.1.0:
+  version "7.1.0"
+  resolved 
"https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c";
+  integrity 
sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
+
 aggregate-error@^3.0.0:
   version "3.0.1"
   resolved 
"https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0";
@@ -1324,6 +1353,11 @@ builtin-modules@^1.1.1:
   resolved 
"https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f";
   integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
 
+builtin-modules@^3.1.0:
+  version "3.1.0"
+  resolved 
"https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484";
+  integrity 
sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
+
 builtin-status-codes@^3.0.0:
   version "3.0.0"
   resolved 
"https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8";
@@ -2454,6 +2488,11 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
   resolved 
"https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d";
   integrity 
sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
+estree-walker@^0.6.1:
+  version "0.6.1"
+  resolved 
"https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362";
+  integrity 
sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
+
 esutils@^2.0.2:
   version "2.0.3"
   resolved 
"https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64";
@@ -3699,6 +3738,11 @@ is-installed-globally@^0.1.0:
     global-dirs "^0.1.0"
     is-path-inside "^1.0.0"
 
+is-module@^1.0.0:
+  version "1.0.0"
+  resolved 
"https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591";
+  integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
+
 is-negated-glob@^1.0.0:
   version "1.0.0"
   resolved 
"https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2";
@@ -3791,6 +3835,13 @@ is-promise@^2.1.0:
   resolved 
"https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa";
   integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
 
+is-reference@^1.1.2:
+  version "1.1.4"
+  resolved 
"https://registry.yarnpkg.com/is-reference/-/is-reference-1.1.4.tgz#3f95849886ddb70256a3e6d062b1a68c13c51427";
+  integrity 
sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==
+  dependencies:
+    "@types/estree" "0.0.39"
+
 is-regex@^1.0.4:
   version "1.0.4"
   resolved 
"https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491";
@@ -4303,6 +4354,13 @@ lunr@^2.3.8:
   resolved 
"https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072";
   integrity 
sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
 
+magic-string@^0.25.2:
+  version "0.25.4"
+  resolved 
"https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.4.tgz#325b8a0a79fc423db109b77fd5a19183b7ba5143";
+  integrity 
sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==
+  dependencies:
+    sourcemap-codec "^1.4.4"
+
 make-dir@^1.0.0:
   version "1.3.0"
   resolved 
"https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c";
@@ -5978,6 +6036,13 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, 
resolve@^1.3.2, resolve@^1.4.0:
   dependencies:
     path-parse "^1.0.6"
 
+resolve@^1.11.0, resolve@^1.11.1:
+  version "1.13.1"
+  resolved 
"https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16";
+  integrity 
sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==
+  dependencies:
+    path-parse "^1.0.6"
+
 responselike@^1.0.2:
   version "1.0.2"
   resolved 
"https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7";
@@ -6026,6 +6091,44 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
     hash-base "^3.0.0"
     inherits "^2.0.1"
 
+rollup-plugin-commonjs@^10.1.0:
+  version "10.1.0"
+  resolved 
"https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz#417af3b54503878e084d127adf4d1caf8beb86fb";
+  integrity 
sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==
+  dependencies:
+    estree-walker "^0.6.1"
+    is-reference "^1.1.2"
+    magic-string "^0.25.2"
+    resolve "^1.11.0"
+    rollup-pluginutils "^2.8.1"
+
+rollup-plugin-node-resolve@^5.2.0:
+  version "5.2.0"
+  resolved 
"https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz#730f93d10ed202473b1fb54a5997a7db8c6d8523";
+  integrity 
sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==
+  dependencies:
+    "@types/resolve" "0.0.8"
+    builtin-modules "^3.1.0"
+    is-module "^1.0.0"
+    resolve "^1.11.1"
+    rollup-pluginutils "^2.8.1"
+
+rollup-pluginutils@^2.5.0, rollup-pluginutils@^2.8.1:
+  version "2.8.2"
+  resolved 
"https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e";
+  integrity 
sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
+  dependencies:
+    estree-walker "^0.6.1"
+
+rollup@^1.27.8:
+  version "1.27.8"
+  resolved 
"https://registry.yarnpkg.com/rollup/-/rollup-1.27.8.tgz#94288a957af9f4c2380b73a17494d87705997d0f";
+  integrity 
sha512-EVoEV5rAWl+5clnGznt1KY8PeVkzVQh/R0d2s3gHEkN7gfoyC4JmvIVuCtPbYE8NM5Ep/g+nAmvKXBjzaqTsHA==
+  dependencies:
+    "@types/estree" "*"
+    "@types/node" "*"
+    acorn "^7.1.0"
+
 run-parallel@^1.1.9:
   version "1.1.9"
   resolved 
"https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679";
@@ -6300,6 +6403,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
   resolved 
"https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263";
   integrity 
sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
+sourcemap-codec@^1.4.4:
+  version "1.4.6"
+  resolved 
"https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz#e30a74f0402bad09807640d39e971090a08ce1e9";
+  integrity 
sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==
+
 sparkles@^1.0.0:
   version "1.0.1"
   resolved 
"https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c";

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



reply via email to

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